#include <libxml/parser.h>
#include <memory>
-using xml_parser_ctx_uptr = std::unique_ptr<
+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 */
#include <string.h>
#include <unistd.h>
+namespace ll = lttng::libxml;
+
#if defined(LIBXML_XPATH_ENABLED)
static int opt_verbose;
LTTNG_ASSERT(xml_path);
LTTNG_ASSERT(xpath);
- xml_parser_ctx_uptr parserCtx{ xmlNewParserCtxt() };
+ ll::parser_ctx_uptr parserCtx{ xmlNewParserCtxt() };
if (!parserCtx) {
fprintf(stderr, "ERR: could not allocate an XML parser context\n");
#include "common.hpp"
+#include <common/scope-exit.hpp>
+
+#include <iostream>
#include <libxml/parser.h>
#include <unistd.h>
+namespace ll = lttng::libxml;
+
int main()
{
- xmlDocPtr doc = NULL;
-
- /* Init libxml. */
- xmlInitParser();
-
- {
- xml_parser_ctx_uptr parserCtx{ xmlNewParserCtxt() };
-
- /* Parse the XML document from stdin. */
- doc = xmlCtxtReadFd(
- parserCtx.get(), STDIN_FILENO, nullptr, nullptr, XML_PARSE_NOBLANKS);
- if (!doc) {
- fprintf(stderr, "ERR parsing: xml input invalid");
- return -1;
- }
-
- xmlDocFormatDump(stdout, doc, 1);
-
- xmlFreeDoc(doc);
+ 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;
}
- /* Shutdown libxml. */
- xmlCleanupParser();
+ xmlDocFormatDump(stdout, doc.get(), 1);
return 0;
}