Import CStringView from the Babeltrace tree master
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Tue, 23 Apr 2024 20:46:47 +0000 (16:46 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Wed, 8 May 2024 19:52:29 +0000 (19:52 +0000)
The class is imported as of 1dcaf4b74 in the babeltrace tree. It is
renamed and reformated to fit the LTTng-tools conventions.

No changes in behaviour are intended.

Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: I8acc3833c52c4ac23a91af87157aade0b4bbb7c1

13 files changed:
.clang-format
src/bin/lttng-relayd/sessiond-trace-chunks.cpp
src/bin/lttng-sessiond/ust-app.cpp
src/common/Makefile.am
src/common/consumer/consumer.hpp
src/common/event-rule/kernel-syscall.cpp
src/common/string-utils/c-string-view.hpp [new file with mode: 0644]
src/common/type-traits.hpp [new file with mode: 0644]
tests/utils/xml-utils/Makefile.am
tests/utils/xml-utils/common.hpp [new file with mode: 0644]
tests/utils/xml-utils/extract_xml.cpp
tests/utils/xml-utils/pretty_xml.c [deleted file]
tests/utils/xml-utils/pretty_xml.cpp [new file with mode: 0644]

index 28ea69873145dcb40b167d659a3b828b8968e9b8..8fcee64f873254026f520850185a7b610cb5a1c8 100644 (file)
@@ -35,7 +35,6 @@ BraceWrapping:
   SplitEmptyFunction: true
 BreakBeforeBinaryOperators: None
 BreakBeforeTernaryOperators: false
-BreakConstructorInitializers: AfterColon
 BreakStringLiterals: false
 ColumnLimit: 100
 ConstructorInitializerAllOnOneLineOrOnePerLine: true
index 9d793c9bcf79315e722447fcb3c205f785a60c54..2326878fb9fd6a9dd2f9d6dfd8dc8dd4504243f1 100644 (file)
@@ -78,8 +78,8 @@ struct trace_chunk_registry_ht_element {
 
 static unsigned long trace_chunk_registry_ht_key_hash(const struct trace_chunk_registry_ht_key *key)
 {
-       const uint64_t uuid_h1 = *reinterpret_cast<const uint64_t *>(&key->sessiond_uuid[0]);
-       const uint64_t uuid_h2 = *reinterpret_cast<const uint64_t *>(&key->sessiond_uuid[1]);
+       const uint64_t uuid_h1 = reinterpret_cast<const uint64_t *>(key->sessiond_uuid.data())[0];
+       const uint64_t uuid_h2 = reinterpret_cast<const uint64_t *>(key->sessiond_uuid.data())[1];
 
        return hash_key_u64(&uuid_h1, lttng_ht_seed) ^ hash_key_u64(&uuid_h2, lttng_ht_seed);
 }
index 12250edfdaefb1341736ba5b78c62a53ceba1c8e..d993b7b4439059f2448940f7b3130a2e638e3954 100644 (file)
@@ -6025,8 +6025,8 @@ static void ust_app_synchronize_event_notifier_rules(struct ust_app *app)
        }
 
        for (i = 0; i < count; i++) {
-               struct lttng_condition *condition;
-               struct lttng_event_rule *event_rule;
+               const struct lttng_condition *condition;
+               const struct lttng_event_rule *event_rule;
                struct lttng_trigger *trigger;
                const struct ust_app_event_notifier_rule *looked_up_event_notifier_rule;
                enum lttng_condition_status condition_status;
@@ -6036,7 +6036,7 @@ static void ust_app_synchronize_event_notifier_rules(struct ust_app *app)
                LTTNG_ASSERT(trigger);
 
                token = lttng_trigger_get_tracer_token(trigger);
-               condition = lttng_trigger_get_condition(trigger);
+               condition = lttng_trigger_get_const_condition(trigger);
 
                if (lttng_condition_get_type(condition) !=
                    LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES) {
@@ -6044,8 +6044,8 @@ static void ust_app_synchronize_event_notifier_rules(struct ust_app *app)
                        continue;
                }
 
-               condition_status = lttng_condition_event_rule_matches_borrow_rule_mutable(
-                       condition, &event_rule);
+               condition_status =
+                       lttng_condition_event_rule_matches_get_rule(condition, &event_rule);
                LTTNG_ASSERT(condition_status == LTTNG_CONDITION_STATUS_OK);
 
                if (lttng_event_rule_get_domain_type(event_rule) == LTTNG_DOMAIN_KERNEL) {
index 34fd83452802f5b8caa21a347ce4264e693f1e88..8170e6e5add57dc5c66e459b9612e2bbbb2a2c4a 100644 (file)
@@ -115,6 +115,7 @@ libcommon_lgpl_la_SOURCES = \
        time.cpp \
        tracker.cpp tracker.hpp \
        trigger.cpp \
+       type-traits.hpp \
        unix.cpp unix.hpp \
        uri.cpp uri.hpp \
        userspace-probe.cpp \
@@ -432,6 +433,7 @@ endif
 # libstring-utils
 noinst_LTLIBRARIES += libstring-utils.la
 libstring_utils_la_SOURCES = \
+       string-utils/c-string-view.hpp \
        string-utils/format.hpp \
        string-utils/string-utils.cpp \
        string-utils/string-utils.hpp
index 310969172d73f656a258d038cfdb1c0c55c9441f..851b3e2b8137eaef4d5904b19deb81a3f9921bdf 100644 (file)
@@ -922,7 +922,7 @@ void lttng_consumer_set_command_sock_path(struct lttng_consumer_local_data *ctx,
  * on error.
  */
 int lttng_consumer_send_error(struct lttng_consumer_local_data *ctx,
-               enum lttcomm_return_code error_code);
+                             enum lttcomm_return_code error_code);
 
 /*
  * Called from signal handler to ensure a clean exit.
index 23a432aacaaff285e6f0e3cb735d8cb1b4b3f26a..933c3543fcc155d5e74e3310089397155d9d4a76 100644 (file)
@@ -133,6 +133,10 @@ static bool lttng_event_rule_kernel_syscall_is_equal(const struct lttng_event_ru
                goto end;
        }
 
+       if (a->emission_site != b->emission_site) {
+               goto end;
+       }
+
        is_equal = true;
 end:
        return is_equal;
diff --git a/src/common/string-utils/c-string-view.hpp b/src/common/string-utils/c-string-view.hpp
new file mode 100644 (file)
index 0000000..6b175ea
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 2023 Philippe Proulx <pproulx@efficios.com>
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef LTTNG_C_STRING_VIEW_HPP
+#define LTTNG_C_STRING_VIEW_HPP
+
+#include <common/format.hpp>
+#include <common/type-traits.hpp>
+
+#include <cstddef>
+#include <cstring>
+#include <functional>
+#include <string>
+
+namespace lttng {
+
+/*
+ * A view on a constant null-terminated C string.
+ */
+class c_string_view final {
+public:
+       /*
+        * Builds an empty view (data() returns `nullptr`).
+        *
+        * Intentionally not explicit.
+        */
+       constexpr c_string_view() noexcept = default;
+
+       /*
+        * Builds a view of the C string `str` (may be `nullptr`).
+        *
+        * Intentionally not explicit.
+        */
+       /* NOLINTBEGIN(google-explicit-constructor) */
+       constexpr c_string_view(const char *const str) noexcept : _str{ str }
+       {
+       }
+       /* NOLINTEND(google-explicit-constructor) */
+
+       /*
+        * Builds a view of the string `str`.
+        */
+       /* NOLINTBEGIN(google-explicit-constructor) */
+       c_string_view(const std::string& str) noexcept : _str{ str.c_str() }
+       {
+       }
+       /* NOLINTEND */
+
+       /*
+        * Makes this view view the C string `str` (may be `nullptr`).
+        */
+       c_string_view& operator=(const char *const str) noexcept
+       {
+               _str = str;
+               return *this;
+       }
+
+       /*
+        * Viewed null-terminated C string (may be `nullptr`).
+        */
+       const char *data() const noexcept
+       {
+               return _str;
+       }
+
+       /*
+        * Alias of data().
+        */
+       operator const char *() const noexcept /* NOLINT(google-explicit-constructor) */
+       {
+               return this->data();
+       }
+
+       /*
+        * Evaluate as boolean (false means an empty string).
+        */
+       operator bool() const noexcept /* NOLINT(google-explicit-constructor) */
+       {
+               return *this->data();
+       }
+
+       /*
+        * Alias of data().
+        */
+       const char *operator*() const noexcept
+       {
+               return this->data();
+       }
+
+       /*
+        * Alias of data().
+        *
+        * data() must not return `nullptr`.
+        */
+       const char *begin() const noexcept
+       {
+               return this->data();
+       }
+
+       /*
+        * Pointer to the null character of the viewed C string.
+        *
+        * data() must not return `nullptr`.
+        */
+       const char *end() const noexcept
+       {
+               return _str + this->len();
+       }
+
+       /*
+        * Length of the viewed C string, excluding the null character.
+        *
+        * data() must not return `nullptr`.
+        */
+       std::size_t len() const noexcept
+       {
+               return std::strlen(_str);
+       }
+
+       /*
+        * Returns an `std::string` instance containing a copy of the viewed
+        * C string.
+        *
+        * data() must not return `nullptr`.
+        */
+       std::string str() const
+       {
+               return std::string{ _str };
+       }
+
+       /*
+        * Alias of str().
+        */
+       operator std::string() const /* NOLINT(google-explicit-constructor) */
+       {
+               return this->str();
+       }
+
+       /*
+        * Returns the character at index `i`.
+        *
+        * `i` must be less than what len() returns.
+        *
+        * data() must not return `nullptr`.
+        */
+       char operator[](const std::size_t i) const noexcept
+       {
+               return _str[i];
+       }
+
+       bool startsWith(const lttng::c_string_view prefix) const noexcept
+       {
+               return std::strncmp(_str, (const char *) prefix, prefix.len()) == 0;
+       }
+
+private:
+       const char *_str = nullptr;
+};
+
+inline const char *format_as(const c_string_view& str)
+{
+       return str ? *str : "(null)";
+}
+
+namespace internal {
+
+template <typename StrT>
+const char *as_const_char_ptr(StrT&& val) noexcept
+{
+       return val.data();
+}
+
+inline const char *as_const_char_ptr(const char *const val) noexcept
+{
+       return val;
+}
+
+template <typename StrT>
+using comparable_with_c_string_view = lttng::traits::
+       is_one_of<typename std::decay<StrT>::type, c_string_view, std::string, const char *>;
+
+} /* namespace internal */
+
+/*
+ * Returns true if `lhs` is equal to `rhs`.
+ *
+ * `LhsT` and `RhsT` may be any of:
+ *
+ * • `const char *`
+ * • `std::string`
+ * • `c_string_view`
+ *
+ * Both `lhs` and `rhs` must not have an underlying `nullptr` raw data.
+ */
+template <
+       typename LhsT,
+       typename RhsT,
+       typename =
+               typename std::enable_if<internal::comparable_with_c_string_view<LhsT>::value>::type,
+       typename =
+               typename std::enable_if<internal::comparable_with_c_string_view<RhsT>::value>::type>
+bool operator==(LhsT&& lhs, RhsT&& rhs) noexcept
+{
+       const auto raw_lhs = internal::as_const_char_ptr(lhs);
+       const auto raw_rhs = internal::as_const_char_ptr(rhs);
+
+       return std::strcmp(raw_lhs, raw_rhs) == 0;
+}
+
+/*
+ * Returns true if `lhs` is not equal to `rhs`.
+ *
+ * `LhsT` and `RhsT` may be any of:
+ *
+ * • `const char *`
+ * • `std::string`
+ * • `c_string_view`
+ *
+ * Both `lhs` and `rhs` must not have an underlying `nullptr` raw data.
+ */
+template <
+       typename LhsT,
+       typename RhsT,
+       typename =
+               typename std::enable_if<internal::comparable_with_c_string_view<LhsT>::value>::type,
+       typename =
+               typename std::enable_if<internal::comparable_with_c_string_view<RhsT>::value>::type>
+bool operator!=(LhsT&& lhs, RhsT&& rhs) noexcept
+{
+       return !(std::forward<LhsT>(lhs) == std::forward<RhsT>(rhs));
+}
+
+} /* namespace lttng */
+
+/*
+ * Appends `rhs` to `lhs`.
+ */
+inline void operator+=(std::string& lhs, lttng::c_string_view rhs)
+{
+       lhs += rhs.data();
+}
+
+namespace std {
+template <>
+struct hash<lttng::c_string_view> {
+       std::size_t operator()(const lttng::c_string_view& str) const
+       {
+               auto hash_value = std::hash<char>{}('\0');
+
+               for (auto character : str) {
+                       hash_value ^= std::hash<decltype(character)>{}(character);
+               }
+
+               return hash_value;
+       }
+};
+} /* namespace std */
+
+#endif /* LTTNG_C_STRING_VIEW_HPP */
diff --git a/src/common/type-traits.hpp b/src/common/type-traits.hpp
new file mode 100644 (file)
index 0000000..3801bf1
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2023 Philippe Proulx <pproulx@efficios.com>
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef LTTNG_TYPE_TRAITS_HPP
+#define LTTNG_TYPE_TRAITS_HPP
+
+#include <type_traits>
+
+namespace lttng {
+namespace traits {
+
+/*
+ * Provides the member constant `value` equal to:
+ *
+ * `T` is in the list of types `Ts`:
+ *     `true`
+ *
+ * Otherwise:
+ *     `false`
+ */
+template <typename T, typename... Ts>
+struct is_one_of : std::false_type {
+};
+
+template <typename T, typename... Ts>
+struct is_one_of<T, T, Ts...> : std::true_type {
+};
+
+template <typename T, typename U, typename... Ts>
+struct is_one_of<T, U, Ts...> : is_one_of<T, Ts...> {
+};
+} /* namespace traits */
+} /* namespace lttng */
+
+#endif /* LTTNG_TYPE_TRAITS_HPP */
index 7997d94e126369e694114d5b7584d593ba637c8b..5890eef27533c185f1c7033c85b8a0f14f707b3c 100644 (file)
@@ -1,5 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
+EXTRA_DIST = common.hpp
+
 noinst_PROGRAMS = validate_xml extract_xml pretty_xml
 validate_xml_SOURCES = validate_xml.cpp
 validate_xml_CPPFLAGS = $(libxml2_CFLAGS) $(AM_CPPFLAGS)
@@ -9,7 +11,7 @@ extract_xml_SOURCES = extract_xml.cpp
 extract_xml_CPPFLAGS = $(libxml2_CFLAGS) $(AM_CPPFLAGS)
 extract_xml_LDADD = $(libxml2_LIBS)
 
-pretty_xml_SOURCES = pretty_xml.c
+pretty_xml_SOURCES = pretty_xml.cpp
 pretty_xml_CPPFLAGS = $(libxml2_CFLAGS) $(AM_CPPFLAGS)
 pretty_xml_LDADD = $(libxml2_LIBS)
 
diff --git a/tests/utils/xml-utils/common.hpp b/tests/utils/xml-utils/common.hpp
new file mode 100644 (file)
index 0000000..01a9b52
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2024 EfficiOS Inc.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ */
+
+#ifndef TESTS_UTILS_XML_UTILS_COMMON_HPP
+#define TESTS_UTILS_XML_UTILS_COMMON_HPP
+
+#include "common/make-unique-wrapper.hpp"
+
+#include <libxml/parser.h>
+#include <memory>
+
+namespace lttng {
+namespace libxml {
+
+using parser_ctx_uptr = std::unique_ptr<
+       xmlParserCtxt,
+       lttng::memory::create_deleter_class<xmlParserCtxt, xmlFreeParserCtxt>::deleter>;
+using doc_uptr =
+       std::unique_ptr<xmlDoc, lttng::memory::create_deleter_class<xmlDoc, xmlFreeDoc>::deleter>;
+
+/*
+ * Manage the global parser context of libxml2.
+ * There should only be one instance of this class per process.
+ */
+class global_parser_context {
+public:
+       global_parser_context()
+       {
+               xmlInitParser();
+       }
+
+       ~global_parser_context()
+       {
+               xmlCleanupParser();
+       }
+
+       /* Deactivate copy and assignment. */
+       global_parser_context(const global_parser_context&) = delete;
+       global_parser_context(global_parser_context&&) = delete;
+       global_parser_context& operator=(const global_parser_context&) = delete;
+       global_parser_context& operator=(global_parser_context&&) = delete;
+};
+} /* namespace libxml */
+} /* namespace lttng */
+#endif /* TESTS_UTILS_XML_UTILS_COMMON_HPP */
index 3995dde48a27d9d96485f148222b883f58f4ef10..280f2ed0284b80736ce92485479c488ce75aad1b 100644 (file)
@@ -24,6 +24,8 @@
  *     node;b;
  *     node;c;
  */
+#include "common.hpp"
+
 #include <common/defaults.hpp>
 
 #include <libxml/parser.h>
@@ -36,6 +38,8 @@
 #include <string.h>
 #include <unistd.h>
 
+namespace ll = lttng::libxml;
+
 #if defined(LIBXML_XPATH_ENABLED)
 
 static int opt_verbose;
@@ -176,8 +180,15 @@ static int extract_xpath(const char *xml_path, const xmlChar *xpath)
        LTTNG_ASSERT(xml_path);
        LTTNG_ASSERT(xpath);
 
+       ll::parser_ctx_uptr parserCtx{ xmlNewParserCtxt() };
+
+       if (!parserCtx) {
+               fprintf(stderr, "ERR: could not allocate an XML parser context\n");
+               return -1;
+       }
+
        /* Parse the xml file */
-       doc = xmlParseFile(xml_path);
+       doc = xmlCtxtReadFile(parserCtx.get(), xml_path, nullptr, XML_PARSE_NOBLANKS);
        if (!doc) {
                fprintf(stderr, "ERR parsing: xml file invalid \"%s\"\n", xml_path);
                return -1;
@@ -253,7 +264,6 @@ int main(int argc, char **argv)
 
        /* Init libxml */
        xmlInitParser();
-       xmlKeepBlanksDefault(0);
        if (access(argv[optind], F_OK)) {
                fprintf(stderr, "ERR:%s\n", "Xml path not valid");
                return -1;
diff --git a/tests/utils/xml-utils/pretty_xml.c b/tests/utils/xml-utils/pretty_xml.c
deleted file mode 100644 (file)
index 3f296f0..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2021 EfficiOS Inc.
- *
- * SPDX-License-Identifier: GPL-2.0-only
- *
- */
-
-/*
- * Prettyfi a xml input from stdin to stddout.
- * This allows a more human friendly format for xml testing when problems occur.
- */
-
-#include <libxml/parser.h>
-
-int main(void)
-{
-       xmlDocPtr doc = NULL;
-
-       /* Init libxml. */
-       xmlInitParser();
-       xmlKeepBlanksDefault(0);
-
-       /* Parse the XML document from stdin. */
-       doc = xmlParseFile("-");
-       if (!doc) {
-               fprintf(stderr, "ERR parsing: xml input invalid");
-               return -1;
-       }
-
-       xmlDocFormatDump(stdout, doc, 1);
-
-       xmlFreeDoc(doc);
-       /* Shutdown libxml. */
-       xmlCleanupParser();
-
-       return 0;
-}
diff --git a/tests/utils/xml-utils/pretty_xml.cpp b/tests/utils/xml-utils/pretty_xml.cpp
new file mode 100644 (file)
index 0000000..8a6e967
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 EfficiOS Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ */
+
+/*
+ * Prettyfi a xml input from stdin to stddout.
+ * This allows a more human friendly format for xml testing when problems occur.
+ */
+
+#include "common.hpp"
+
+#include <common/scope-exit.hpp>
+
+#include <iostream>
+#include <libxml/parser.h>
+#include <unistd.h>
+
+namespace ll = lttng::libxml;
+
+int main()
+{
+       const ll::global_parser_context global_parser_context;
+       const ll::parser_ctx_uptr parserCtx{ xmlNewParserCtxt() };
+
+       /* Parse the XML document from stdin. */
+       const ll::doc_uptr doc{ xmlCtxtReadFd(
+               parserCtx.get(), STDIN_FILENO, nullptr, nullptr, XML_PARSE_NOBLANKS) };
+       if (!doc) {
+               std::cerr << "Error: invalid XML input on stdin\n";
+               return -1;
+       }
+
+       xmlDocFormatDump(stdout, doc.get(), 1);
+
+       return 0;
+}
This page took 0.038885 seconds and 4 git commands to generate.