Move xml utils from mi subfolder to xml-utils folder
authorJonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Wed, 26 May 2021 20:39:12 +0000 (16:39 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Wed, 30 Jun 2021 16:13:55 +0000 (12:13 -0400)
Signed-off-by: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: I268dc544bf4f72f61a701ac3efd0b12488cc2f64

14 files changed:
.gitignore
configure.ac
tests/regression/tools/mi/Makefile.am
tests/regression/tools/mi/extract_xml.c [deleted file]
tests/regression/tools/mi/test_mi
tests/regression/tools/mi/validate_xml.c [deleted file]
tests/regression/tools/mi/validate_xml.h [deleted file]
tests/regression/tools/relayd-grouping/test_ust
tests/regression/tools/rotation/test_save_load_mi
tests/regression/tools/save-load/test_load
tests/utils/Makefile.am
tests/utils/xml-utils/Makefile.am [new file with mode: 0644]
tests/utils/xml-utils/extract_xml.c [new file with mode: 0644]
tests/utils/xml-utils/validate_xml.c [new file with mode: 0644]

index aebc12bf833d36f2e68be6d30e92317f1836b26c..d9ecbd3d3797d88f6f51a2b3e5a36f8c43660146 100644 (file)
@@ -102,8 +102,6 @@ compile_commands.json
 /tests/utils/testapp/gen-ust-events-ns/gen-ust-events-ns
 /tests/regression/tools/health/health_check
 /tests/regression/kernel/select_poll_epoll
-/tests/regression/tools/mi/extract_xml
-/tests/regression/tools/mi/validate_xml
 /tests/regression/tools/notification/base_client
 /tests/regression/tools/notification/notification
 /tests/regression/tools/rotation/schedule_api
@@ -141,6 +139,8 @@ compile_commands.json
 /tests/utils/testapp/gen-ust-tracef/gen-ust-tracef
 /tests/utils/testapp/gen-syscall-events/gen-syscall-events
 /tests/utils/testapp/gen-kernel-test-events/gen-kernel-test-events
+/tests/utils/xml-utils/extract_xml
+/tests/utils/xml-utils/validate_xml
 /tests/regression/tools/live/live_test
 /tests/unit/ini_config/ini_config
 /tests/perf/find_event
index 0da5a04e4f79b83c56c77be4f719d390ccc07de7..102a1d0f4b1b9351ca8397b8bab6e2b896ce1540 100644 (file)
@@ -1197,6 +1197,7 @@ AC_CONFIG_FILES([
        tests/utils/testapp/userspace-probe-elf-binary/Makefile
        tests/utils/testapp/userspace-probe-elf-cxx-binary/Makefile
        tests/utils/testapp/userspace-probe-sdt-binary/Makefile
+       tests/utils/xml-utils/Makefile
 ])
 
 # Inject variable into python test script.
index c5bd827b1ddddaa9c79701990319ad4eb1f6b6a4..bfa42bfc33494e799b5808186b958658e0ee16e1 100644 (file)
@@ -1,14 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
-noinst_PROGRAMS = validate_xml extract_xml
-validate_xml_SOURCES = validate_xml.c
-validate_xml_CPPFLAGS = $(libxml2_CFLAGS) $(AM_CPPFLAGS)
-validate_xml_LDADD = $(libxml2_LIBS)
-
-extract_xml_SOURCES = extract_xml.c
-extract_xml_CPPFLAGS = $(libxml2_CFLAGS) $(AM_CPPFLAGS)
-extract_xml_LDADD = $(libxml2_LIBS)
-
 noinst_SCRIPTS = test_mi
 EXTRA_DIST = test_mi
 
diff --git a/tests/regression/tools/mi/extract_xml.c b/tests/regression/tools/mi/extract_xml.c
deleted file mode 100644 (file)
index 32c57e6..0000000
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright (C) 2014 Jonathan Rajotte <jonathan.r.julien@gmail.com>
- *
- * SPDX-License-Identifier: GPL-2.0-only
- *
- */
-
-/*
- * Usage: extract_xml [-v|-e] xml_path xpath_expression
- * Evaluate XPath expression and prints result node set.
- * args[1] path to the xml file
- * args[2] xpath expression to extract
- * If -e look if node exist return "true" else nothing
- * If -v is set the name of the node will appear with his value delimited by
- * a semicolon(;)
- * Ex:
- * Command:extract_xml ../file.xml /test/node/text()
- * Output:
- *     a
- *     b
- *     c
- * With -v
- *     node;a;
- *     node;b;
- *     node;c;
- */
-#include <assert.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <libxml/tree.h>
-#include <libxml/parser.h>
-#include <libxml/xpath.h>
-#include <libxml/xpathInternals.h>
-#include <common/defaults.h>
-
-#if defined(LIBXML_XPATH_ENABLED)
-
-static int opt_verbose;
-static int node_exist;
-static bool result = false;
-
-/**
- * print_xpath_nodes:
- * nodes:  the nodes set.
- * output: the output file handle.
- *
- * Print the node content to the file
- */
-static int print_xpath_nodes(xmlDocPtr doc, xmlNodeSetPtr nodes, FILE *output)
-{
-       int ret = 0;
-       int size;
-       int i;
-
-       xmlNodePtr cur;
-       xmlChar *node_child_value_string = NULL;
-
-       assert(output);
-       size = (nodes) ? nodes->nodeNr : 0;
-
-       for (i = 0; i < size; ++i) {
-               assert(nodes->nodeTab[i]);
-
-               if (nodes->nodeTab[i]->type == XML_NAMESPACE_DECL) {
-                       fprintf(stderr, "ERR:%s\n",
-                                       "This executable does not support xml namespacing\n");
-                       ret = -1;
-                       goto end;
-               } else if (nodes->nodeTab[i]->type == XML_ELEMENT_NODE) {
-                       cur = nodes->nodeTab[i];
-
-                       if (xmlChildElementCount(cur) == 0) {
-                               if (xmlNodeIsText(cur->children)) {
-                                       node_child_value_string = xmlNodeListGetString(doc,
-                                                       cur->children, 1);
-                                       if (node_exist) {
-                                               result = true;
-                                       } else if (opt_verbose) {
-                                               fprintf(output, "%s;%s;\n", cur->name,
-                                                               node_child_value_string);
-                                       } else {
-                                               fprintf(output, "%s\n",
-                                                               node_child_value_string);
-                                       }
-                                       xmlFree(node_child_value_string);
-                               } else {
-                                       /* We don't want to print non-final element */
-                                       if (node_exist) {
-                                               result = true;
-                                       } else {
-                                               fprintf(stderr, "ERR:%s\n",
-                                                               "Xpath expression return non-final xml element");
-                                               ret = -1;
-                                               goto end;
-                                       }
-                               }
-                       } else {
-                               if (node_exist) {
-                                       result = true;
-                               } else {
-                                       /* We don't want to print non-final element */
-                                       fprintf(stderr, "ERR:%s\n",
-                                                       "Xpath expression return non-final xml element");
-                                       ret = -1;
-                                       goto end;
-                               }
-                       }
-
-               } else {
-                       cur = nodes->nodeTab[i];
-                       if (node_exist) {
-                               result = true;
-                       } else if (opt_verbose) {
-                               fprintf(output, "%s;%s;\n", cur->parent->name, cur->content);
-                       } else {
-                               fprintf(output, "%s\n", cur->content);
-                       }
-               }
-       }
-       /* Command Success */
-       ret = 0;
-
-end:
-       return ret;
-}
-
-static int register_lttng_namespace(xmlXPathContextPtr xpathCtx)
-{
-       int ret;
-       xmlChar *prefix;
-       xmlChar *ns = NULL;
-
-       prefix = xmlCharStrdup("lttng");
-       if (!prefix) {
-               ret = -1;
-               goto end;
-       }
-
-       ns = xmlCharStrdup(DEFAULT_LTTNG_MI_NAMESPACE);
-       if (!ns) {
-               ret = -1;
-               goto end;
-       }
-
-       ret = xmlXPathRegisterNs(xpathCtx, prefix, ns);
-end:
-       xmlFree(prefix);
-       xmlFree(ns);
-       return ret;
-}
-
-/*
- * Extract element corresponding to xpath
- * xml_path     The path to the xml file
- * xpath:       The xpath to evaluate.
- *
- * Evaluate an xpath expression onto an xml file.
- * and print the result one by line.
- *
- * Returns 0 on success and a negative value otherwise.
- */
-static int extract_xpath(const char *xml_path, const xmlChar *xpath)
-{
-       int ret;
-       xmlDocPtr doc = NULL;
-       xmlXPathContextPtr xpathCtx = NULL;
-       xmlXPathObjectPtr xpathObj = NULL;
-
-       assert(xml_path);
-       assert(xpath);
-
-       /* Parse the xml file */
-       doc = xmlParseFile(xml_path);
-       if (!doc) {
-               fprintf(stderr, "ERR parsing: xml file invalid \"%s\"\n", xml_path);
-               return -1;
-       }
-
-       /* Initialize a xpath context */
-       xpathCtx = xmlXPathNewContext(doc);
-       if (!xpathCtx) {
-               fprintf(stderr, "ERR: XPath context invalid\n");
-               xmlFreeDoc(doc);
-               return -1;
-       }
-
-       /* Register the LTTng MI namespace */
-       ret = register_lttng_namespace(xpathCtx);
-       if (ret) {
-               fprintf(stderr, "ERR: Could not register lttng namespace\n");
-               xmlXPathFreeContext(xpathCtx);
-               xmlFreeDoc(doc);
-               return -1;
-       }
-
-       /* Evaluate xpath expression */
-       xpathObj = xmlXPathEvalExpression(xpath, xpathCtx);
-       if (!xpathObj) {
-               fprintf(stderr, "ERR: invalid xpath expression \"%s\"\n", xpath);
-               xmlXPathFreeContext(xpathCtx);
-               xmlFreeDoc(doc);
-               return -1;
-       }
-
-       /* Print results */
-       if (print_xpath_nodes(doc, xpathObj->nodesetval, stdout)) {
-               xmlXPathFreeObject(xpathObj);
-               xmlXPathFreeContext(xpathCtx);
-               xmlFreeDoc(doc);
-               return -1;
-       }
-       if (node_exist && result) {
-               fprintf(stdout, "true\n");
-       }
-
-       /* Cleanup */
-       xmlXPathFreeObject(xpathObj);
-       xmlXPathFreeContext(xpathCtx);
-       xmlFreeDoc(doc);
-
-       return 0;
-}
-
-int main(int argc, char **argv)
-{
-       int opt;
-
-       /* Parse command line and process file */
-       while ((opt = getopt(argc, argv, "ve")) != -1) {
-               switch (opt) {
-               case 'v':
-                       opt_verbose = 1;
-                       break;
-               case 'e':
-                       node_exist = 1;
-                       break;
-               default:
-                       abort();
-               }
-       }
-
-       if (!(optind + 1 < argc)) {
-               fprintf(stderr, "ERR:%s\n", "Arguments missing");
-               return -1;
-       }
-
-       /* Init libxml */
-       xmlInitParser();
-       xmlKeepBlanksDefault(0);
-       if (access(argv[optind], F_OK)) {
-               fprintf(stderr, "ERR:%s\n", "Xml path not valid");
-               return -1;
-       }
-       /* Do the main job */
-       if (extract_xpath(argv[optind], (xmlChar *)argv[optind+1])) {
-               return -1;
-       }
-
-       /* Shutdown libxml */
-       xmlCleanupParser();
-
-       return 0;
-}
-
-#else
-int main(void)
-{
-       fprintf(stderr, "XPath support not compiled in\n");
-       return -1;
-}
-#endif
index db5dec50e0a6d5b7fff5efc0b72c3c9f80b18f39..b3b637865456174b3235164b2d396edc52a9b0c6 100755 (executable)
@@ -23,9 +23,10 @@ SESSIOND_LOAD_DIR=$(mktemp --tmpdir -d tmp.test_mi_sessiond_load_dir.XXXXXX)
 OUTPUT_FILE="default.xml"
 
 #Path to custom xml utilities
-XML_VALIDATE="$CURDIR/validate_xml $XSD_PATH"
-XML_EXTRACT="$CURDIR/extract_xml"
-XML_NODE_CHECK="$CURDIR/extract_xml -e"
+XML_UTILS_PATH="$TESTDIR/utils/xml-utils"
+XML_VALIDATE="$XML_UTILS_PATH/validate_xml $XSD_PATH"
+XML_EXTRACT="$XML_UTILS_PATH/extract_xml"
+XML_NODE_CHECK="$XML_UTILS_PATH/extract_xml -e"
 
 XPATH_CMD_OUTPUT="//lttng:command/lttng:output"
 XPATH_COMMAND_SUCCESS="/lttng:command/lttng:success/text()"
diff --git a/tests/regression/tools/mi/validate_xml.c b/tests/regression/tools/mi/validate_xml.c
deleted file mode 100644 (file)
index eafe8b7..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2014 Jonathan Rajotte <jonathan.r.julien@gmail.com>
- *
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- */
-
- /*
-  * This script validate and xml from an xsd.
-  * argv[1] Path of the xsd
-  * argv[2] Path to the XML to be validated
-  */
-
-#include <assert.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <inttypes.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <libxml/xmlschemas.h>
-#include <libxml/parser.h>
-
-#include <lttng/lttng-error.h>
-
-struct validation_ctx {
-       xmlSchemaParserCtxtPtr parser_ctx;
-       xmlSchemaPtr schema;
-       xmlSchemaValidCtxtPtr schema_validation_ctx;
-};
-
-enum command_err_code {
-       CMD_SUCCESS = 0,
-       CMD_ERROR
-};
-
-static
-void xml_error_handler(void *ctx, const char *format, ...)
-{
-       char *err_msg;
-       va_list args;
-       int ret;
-
-       va_start(args, format);
-       ret = vasprintf(&err_msg, format, args);
-       va_end(args);
-       if (ret == -1) {
-               fprintf(stderr, "ERR: %s\n",
-                               "String allocation failed in xml error handle");
-               return;
-       }
-
-       fprintf(stderr, "XML Error: %s\n", err_msg);
-       free(err_msg);
-}
-
-static
-void fini_validation_ctx(
-       struct validation_ctx *ctx)
-{
-       if (ctx->parser_ctx) {
-               xmlSchemaFreeParserCtxt(ctx->parser_ctx);
-       }
-
-       if (ctx->schema) {
-               xmlSchemaFree(ctx->schema);
-       }
-
-       if (ctx->schema_validation_ctx) {
-               xmlSchemaFreeValidCtxt(ctx->schema_validation_ctx);
-       }
-
-       memset(ctx, 0, sizeof(struct validation_ctx));
-}
-
-static
-int init_validation_ctx(
-       struct validation_ctx *ctx, char *xsd_path)
-{
-       int ret;
-
-       if (!xsd_path) {
-               ret = -LTTNG_ERR_NOMEM;
-               goto end;
-       }
-
-       ctx->parser_ctx = xmlSchemaNewParserCtxt(xsd_path);
-       if (!ctx->parser_ctx) {
-               ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
-               goto end;
-       }
-       xmlSchemaSetParserErrors(ctx->parser_ctx, xml_error_handler,
-               xml_error_handler, NULL);
-
-       ctx->schema = xmlSchemaParse(ctx->parser_ctx);
-       if (!ctx->schema) {
-               ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
-               goto end;
-       }
-
-       ctx->schema_validation_ctx = xmlSchemaNewValidCtxt(ctx->schema);
-       if (!ctx->schema_validation_ctx) {
-               ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
-               goto end;
-       }
-
-       xmlSchemaSetValidErrors(ctx->schema_validation_ctx, xml_error_handler,
-                       xml_error_handler, NULL);
-       ret = 0;
-
-end:
-       if (ret) {
-               fini_validation_ctx(ctx);
-       }
-       return ret;
-}
-
-static int validate_xml(const char *xml_file_path, struct validation_ctx *ctx)
-{
-       int ret;
-       xmlDocPtr doc = NULL;
-
-       assert(xml_file_path);
-       assert(ctx);
-
-       /* Open the document */
-       doc = xmlParseFile(xml_file_path);
-       if (!doc) {
-               ret = LTTNG_ERR_MI_IO_FAIL;
-               goto end;
-       }
-
-       /* Validate against the validation ctx (xsd) */
-       ret = xmlSchemaValidateDoc(ctx->schema_validation_ctx, doc);
-       if (ret) {
-               fprintf(stderr, "ERR: %s\n", "XML is not valid againt provided XSD");
-               ret = CMD_ERROR;
-               goto end;
-       }
-
-       ret = CMD_SUCCESS;
-end:
-       return ret;
-
-
-}
-int main(int argc, char **argv, char *env[])
-{
-       int ret;
-       struct validation_ctx ctx = { 0 };
-
-       /* Check if we have all argument */
-       if (argc < 3) {
-               fprintf(stderr, "ERR: %s\n", "Missing arguments");
-               ret = CMD_ERROR;
-               goto end;
-       }
-
-       /* Check if xsd file exist */
-       ret = access(argv[1], F_OK);
-       if (ret < 0) {
-               fprintf(stderr, "ERR: %s\n", "Xsd path not valid");
-               goto end;
-       }
-
-       /* Check if xml to validate exist */
-       ret = access(argv[2], F_OK);
-       if (ret < 0) {
-               fprintf(stderr, "ERR: %s\n", "XML path not valid");
-               goto end;
-       }
-
-       /* initialize the validation ctx */
-       ret = init_validation_ctx(&ctx, argv[1]);
-       if (ret) {
-               goto end;
-       }
-
-       ret = validate_xml(argv[2], &ctx);
-
-       fini_validation_ctx(&ctx);
-
-end:
-       return ret;
-}
diff --git a/tests/regression/tools/mi/validate_xml.h b/tests/regression/tools/mi/validate_xml.h
deleted file mode 100644 (file)
index e69de29..0000000
index 6157413644ab956c6e3a22d8d4be26a136fc6f2c..64fb90e348d25203816f0e90cd506e5d5dbfbea9 100755 (executable)
@@ -18,8 +18,8 @@ CHANNEL_NAME="my_channel"
 
 XSD_PATH=$TESTDIR/../src/common/mi-lttng-4.0.xsd
 
-XML_VALIDATE="$TESTDIR/regression/tools/mi/validate_xml $XSD_PATH"
-XML_EXTRACT="$TESTDIR/regression/tools/mi/extract_xml"
+XML_VALIDATE="$TESTDIR/utils/xml-utils/validate_xml $XSD_PATH"
+XML_EXTRACT="$TESTDIR/utils/xml-utils/extract_xml"
 
 XPATH_CMD_OUTPUT="//lttng:command/lttng:output"
 XPATH_SESSION="$XPATH_CMD_OUTPUT/lttng:sessions/lttng:session"
index fc3b248910f585a6239d6d4814ea574a1e8e7f4b..cb205084111569eaa81de1650ed3af18a01a47a0 100755 (executable)
@@ -20,8 +20,8 @@ LTTNG_BIN="lttng --mi xml"
 
 XSD_PATH=$TESTDIR/../src/common/mi-lttng-4.0.xsd
 
-XML_VALIDATE="$TESTDIR/regression/tools/mi/validate_xml $XSD_PATH"
-XML_EXTRACT="$TESTDIR/regression/tools/mi/extract_xml"
+XML_VALIDATE="$TESTDIR/utils/xml-utils/validate_xml $XSD_PATH"
+XML_EXTRACT="$TESTDIR/utils/xml-utils/extract_xml"
 
 XPATH_CMD_OUTPUT="//lttng:command/lttng:output"
 XPATH_SESSION="$XPATH_CMD_OUTPUT/lttng:sessions/lttng:session"
index 3cf0cc50126146c858f4cd80fb4f8a11ce3267a0..15901f4f09cf046b0a378316f79e2258a81a3611 100755 (executable)
@@ -19,6 +19,7 @@ DIR=$(readlink -f $TESTDIR)
 NUM_TESTS=75
 
 source $TESTDIR/utils/utils.sh
+XML_EXTRACT="$TESTDIR/utils/xml-utils/extract_xml"
 
 # MUST set TESTDIR before calling those functions
 plan_tests $NUM_TESTS
@@ -63,21 +64,21 @@ function test_complex_load()
                break;
        fi
        $TESTDIR/../src/bin/lttng/$LTTNG_BIN --mi XML list $sess -c chan2 > $mi_output_file
-       mi_result=$($CURDIR/../mi/extract_xml $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain[lttng:type='UST']/lttng:channels/lttng:channel[lttng:name='chan2']/lttng:events/lttng:event[lttng:name='uevent_disabled']/lttng:enabled/text()")
+       mi_result=$("$XML_EXTRACT" $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain[lttng:type='UST']/lttng:channels/lttng:channel[lttng:name='chan2']/lttng:events/lttng:event[lttng:name='uevent_disabled']/lttng:enabled/text()")
        if [[ $mi_result = "false" ]]; then
            ok 0 "Disabled event is loaded in disabled state"
        else
            fail "Disabled event is loaded in disabled state"
        fi
 
-       mi_result=$($CURDIR/../mi/extract_xml $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:channels/lttng:channel[lttng:name='chan2']/lttng:events/lttng:event[lttng:name='uevent_disabled']/lttng:enabled/text()")
+       mi_result=$("$XML_EXTRACT" $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:channels/lttng:channel[lttng:name='chan2']/lttng:events/lttng:event[lttng:name='uevent_disabled']/lttng:enabled/text()")
        test $mi_result = "false"
        ok $? "Disabled event is loaded in disabled state"
 
        # Check that uevent_same_name_diff_llevel with log level 6 (TRACE_INFO) is enabled
        # This ensure that the state of events with similar name but not same
        # descriptor tuple (exclusion,filter,loglevel) is restored correctly.
-       mi_result=$($CURDIR/../mi/extract_xml $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:channels/lttng:channel[lttng:name='chan2']/lttng:events/lttng:event[lttng:name='uevent_same_name_diff_llevel' and lttng:loglevel='TRACE_INFO']/lttng:enabled/text()")
+       mi_result=$("$XML_EXTRACT" $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:channels/lttng:channel[lttng:name='chan2']/lttng:events/lttng:event[lttng:name='uevent_same_name_diff_llevel' and lttng:loglevel='TRACE_INFO']/lttng:enabled/text()")
        test $mi_result = "true"
        ok $?  "Enabled event with same name but different loglevel is in disabled state"
 
@@ -132,21 +133,21 @@ function test_trackers()
                break;
        fi
        $TESTDIR/../src/bin/lttng/$LTTNG_BIN --mi XML list "$SESSION_NAME-trackers" > $mi_output_file
-       mi_result=$($CURDIR/../mi/extract_xml -e $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:process_attr_trackers/lttng:vpid_process_attr_tracker/lttng:process_attr_values/lttng:vpid")
+       mi_result=$("$XML_EXTRACT" -e $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:process_attr_trackers/lttng:vpid_process_attr_tracker/lttng:process_attr_values/lttng:vpid")
        if [[ $mi_result = "true" ]]; then
            ok 0 "VPID target is present"
        else
            fail "VPID target missing"
        fi
 
-       mi_result=$($CURDIR/../mi/extract_xml -e $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:process_attr_trackers/lttng:vuid_process_attr_tracker/lttng:process_attr_values/lttng:vuid")
+       mi_result=$("$XML_EXTRACT" -e $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:process_attr_trackers/lttng:vuid_process_attr_tracker/lttng:process_attr_values/lttng:vuid")
        if [[ $mi_result = "true" ]]; then
            ok 0 "VUID target is present"
        else
            fail "VUID target missing"
        fi
 
-       mi_result=$($CURDIR/../mi/extract_xml -e $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:process_attr_trackers/lttng:vgid_process_attr_tracker/lttng:process_attr_values/lttng:vgid")
+       mi_result=$("$XML_EXTRACT" -e $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:process_attr_trackers/lttng:vgid_process_attr_tracker/lttng:process_attr_values/lttng:vgid")
        if [[ $mi_result = "true" ]]; then
            ok 0 "VGID target is present"
        else
@@ -184,7 +185,7 @@ function test_override_url_normal()
        # Url of style file://
        lttng_load_ok "-i $CURDIR/$SESSION_NAME.lttng --override-url=${local_url_override}"
        $TESTDIR/../src/bin/lttng/$LTTNG_BIN --mi XML list "$SESSION_NAME" > $mi_output_file
-       mi_result=$($CURDIR/../mi/extract_xml $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:path")
+       mi_result=$("$XML_EXTRACT" $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:path")
 
        test $mi_result = "${local_path_compare_value}"
        ok $? "Path url file:// override [{$mi_result}, ${local_path_compare_value}]"
@@ -193,7 +194,7 @@ function test_override_url_normal()
        # Url of style /
        lttng_load_ok "-i $CURDIR/$SESSION_NAME.lttng --override-url=${local_path_override}"
        $TESTDIR/../src/bin/lttng/$LTTNG_BIN --mi XML list "$SESSION_NAME" > $mi_output_file
-       mi_result=$($CURDIR/../mi/extract_xml $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:path")
+       mi_result=$("$XML_EXTRACT" $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:path")
 
        test $mi_result = "${local_path_compare_value}"
        ok $? "Path url / override [{$mi_result}, ${local_path_compare_value}]"
@@ -202,7 +203,7 @@ function test_override_url_normal()
        # Url of style net://ip:port:port
        lttng_load_ok "-i $CURDIR/$SESSION_NAME.lttng --override-url=${stream_url_override}"
        $TESTDIR/../src/bin/lttng/$LTTNG_BIN --mi XML list "$SESSION_NAME" > $mi_output_file
-       mi_result=$($CURDIR/../mi/extract_xml $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:path")
+       mi_result=$("$XML_EXTRACT" $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:path")
 
        test "$mi_result" = "${stream_url_compare}"
        ok $? "Path url net://host:port:port override [${mi_result}, ${stream_url_compare}]"
@@ -234,7 +235,7 @@ function test_override_url_snapshot()
        # Url of style file://
        lttng_load_ok "-i $CONFIG_DIR/$local_session_name.lttng --override-url=${url_override}"
        $TESTDIR/../src/bin/lttng/$LTTNG_BIN --mi XML snapshot list-output -s "$local_session_name" > $mi_output_file
-       mi_result=$($CURDIR/../mi/extract_xml $mi_output_file "//lttng:command/lttng:output/lttng:snapshot_action/lttng:output/lttng:session/lttng:snapshots/lttng:snapshot/lttng:ctrl_url")
+       mi_result=$("$XML_EXTRACT" $mi_output_file "//lttng:command/lttng:output/lttng:snapshot_action/lttng:output/lttng:session/lttng:snapshots/lttng:snapshot/lttng:ctrl_url")
 
        test $mi_result = "${path_compare_value}"
        ok $? "Path url file:// override [{$mi_result}, ${path_compare_value}]"
@@ -243,7 +244,7 @@ function test_override_url_snapshot()
        # Url of style /
        lttng_load_ok "-i $CONFIG_DIR/$local_session_name.lttng --override-url=${path_override}"
        $TESTDIR/../src/bin/lttng/$LTTNG_BIN --mi XML snapshot list-output -s "$local_session_name" > $mi_output_file
-       mi_result=$($CURDIR/../mi/extract_xml $mi_output_file "//lttng:command/lttng:output/lttng:snapshot_action/lttng:output/lttng:session/lttng:snapshots/lttng:snapshot/lttng:ctrl_url")
+       mi_result=$("$XML_EXTRACT" $mi_output_file "//lttng:command/lttng:output/lttng:snapshot_action/lttng:output/lttng:session/lttng:snapshots/lttng:snapshot/lttng:ctrl_url")
 
        test $mi_result = "${path_compare_value}"
        ok $? "Path url / override [{$mi_result}, ${path_compare_value}]"
@@ -252,12 +253,12 @@ function test_override_url_snapshot()
        # Url of style net://ip:port:port
        lttng_load_ok "-i $CONFIG_DIR/$local_session_name.lttng --override-url=${stream_url_override}"
        $TESTDIR/../src/bin/lttng/$LTTNG_BIN --mi XML snapshot list-output -s "$local_session_name" > $mi_output_file
-       mi_result=$($CURDIR/../mi/extract_xml $mi_output_file "//lttng:command/lttng:output/lttng:snapshot_action/lttng:output/lttng:session/lttng:snapshots/lttng:snapshot/lttng:ctrl_url")
+       mi_result=$("$XML_EXTRACT" $mi_output_file "//lttng:command/lttng:output/lttng:snapshot_action/lttng:output/lttng:session/lttng:snapshots/lttng:snapshot/lttng:ctrl_url")
 
        test "$mi_result" = "${stream_url_compare_ctrl}"
        ok $? "Path url ctrl net://host:port:port override [${mi_result}, ${stream_url_compare_ctrl}]"
 
-       mi_result=$($CURDIR/../mi/extract_xml $mi_output_file "//lttng:command/lttng:output/lttng:snapshot_action/lttng:output/lttng:session/lttng:snapshots/lttng:snapshot/lttng:data_url")
+       mi_result=$("$XML_EXTRACT" $mi_output_file "//lttng:command/lttng:output/lttng:snapshot_action/lttng:output/lttng:session/lttng:snapshots/lttng:snapshot/lttng:data_url")
 
        test "$mi_result" = "${stream_url_compare_data}"
        ok $? "Path url data net://host:port:port override [${mi_result}, ${stream_url_compare_data}]"
@@ -300,7 +301,7 @@ function test_override_url_live()
        # Url of style net://ip:port:port
        lttng_load_ok "-i $CONFIG_DIR/$local_session_name.lttng --override-url=${stream_url_override}"
        $TESTDIR/../src/bin/lttng/$LTTNG_BIN --mi XML list "$local_session_name" > $mi_output_file
-       mi_result=$($CURDIR/../mi/extract_xml $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:path")
+       mi_result=$("$XML_EXTRACT" $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:path")
 
        test "$mi_result" = "${stream_url_compare}"
        ok $? "Path url net://host:port:port override [${mi_result}, ${stream_url_compare}]"
@@ -328,13 +329,13 @@ function test_override_session_name()
        fi
 
        ${TESTDIR}/../src/bin/lttng/${LTTNG_BIN} --mi XML list "${override_name}" > $mi_output_file
-       mi_result=$($CURDIR/../mi/extract_xml $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:name")
+       mi_result=$("$XML_EXTRACT" $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:name")
 
        test "${mi_result}" = "${override_name}"
        ok $? "Override name successful  [${SESSION_NAME} to ${override_name}]"
 
        # Make sure that the name override did not change something else
-       mi_result=$($CURDIR/../mi/extract_xml $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:path")
+       mi_result=$("$XML_EXTRACT" $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:path")
        test "${mi_result}" = "${output_path}"
        ok $? "Output path is not affected by name override"
 
index c74d10c0673f9bccd4c49ba733dafc6ca58d52c7..1c7c953264ba66d8429d6b03aca3373df4eb96b8 100644 (file)
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
-SUBDIRS = . tap testapp
+SUBDIRS = . tap testapp xml-utils
 
 EXTRA_DIST = utils.sh test_utils.py babelstats.pl warn_processes.sh \
              parse-callstack.py
diff --git a/tests/utils/xml-utils/Makefile.am b/tests/utils/xml-utils/Makefile.am
new file mode 100644 (file)
index 0000000..9b00f70
--- /dev/null
@@ -0,0 +1,24 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+noinst_PROGRAMS = validate_xml extract_xml
+validate_xml_SOURCES = validate_xml.c
+validate_xml_CPPFLAGS = $(libxml2_CFLAGS) $(AM_CPPFLAGS)
+validate_xml_LDADD = $(libxml2_LIBS)
+
+extract_xml_SOURCES = extract_xml.c
+extract_xml_CPPFLAGS = $(libxml2_CFLAGS) $(AM_CPPFLAGS)
+extract_xml_LDADD = $(libxml2_LIBS)
+
+all-local:
+       @if [ x"$(srcdir)" != x"$(builddir)" ]; then \
+               for script in $(EXTRA_DIST); do \
+                       cp -f $(srcdir)/$$script $(builddir); \
+               done; \
+       fi
+
+clean-local:
+       @if [ x"$(srcdir)" != x"$(builddir)" ]; then \
+               for script in $(EXTRA_DIST); do \
+                       rm -f $(builddir)/$$script; \
+               done; \
+       fi
diff --git a/tests/utils/xml-utils/extract_xml.c b/tests/utils/xml-utils/extract_xml.c
new file mode 100644 (file)
index 0000000..32c57e6
--- /dev/null
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2014 Jonathan Rajotte <jonathan.r.julien@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ */
+
+/*
+ * Usage: extract_xml [-v|-e] xml_path xpath_expression
+ * Evaluate XPath expression and prints result node set.
+ * args[1] path to the xml file
+ * args[2] xpath expression to extract
+ * If -e look if node exist return "true" else nothing
+ * If -v is set the name of the node will appear with his value delimited by
+ * a semicolon(;)
+ * Ex:
+ * Command:extract_xml ../file.xml /test/node/text()
+ * Output:
+ *     a
+ *     b
+ *     c
+ * With -v
+ *     node;a;
+ *     node;b;
+ *     node;c;
+ */
+#include <assert.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+#include <common/defaults.h>
+
+#if defined(LIBXML_XPATH_ENABLED)
+
+static int opt_verbose;
+static int node_exist;
+static bool result = false;
+
+/**
+ * print_xpath_nodes:
+ * nodes:  the nodes set.
+ * output: the output file handle.
+ *
+ * Print the node content to the file
+ */
+static int print_xpath_nodes(xmlDocPtr doc, xmlNodeSetPtr nodes, FILE *output)
+{
+       int ret = 0;
+       int size;
+       int i;
+
+       xmlNodePtr cur;
+       xmlChar *node_child_value_string = NULL;
+
+       assert(output);
+       size = (nodes) ? nodes->nodeNr : 0;
+
+       for (i = 0; i < size; ++i) {
+               assert(nodes->nodeTab[i]);
+
+               if (nodes->nodeTab[i]->type == XML_NAMESPACE_DECL) {
+                       fprintf(stderr, "ERR:%s\n",
+                                       "This executable does not support xml namespacing\n");
+                       ret = -1;
+                       goto end;
+               } else if (nodes->nodeTab[i]->type == XML_ELEMENT_NODE) {
+                       cur = nodes->nodeTab[i];
+
+                       if (xmlChildElementCount(cur) == 0) {
+                               if (xmlNodeIsText(cur->children)) {
+                                       node_child_value_string = xmlNodeListGetString(doc,
+                                                       cur->children, 1);
+                                       if (node_exist) {
+                                               result = true;
+                                       } else if (opt_verbose) {
+                                               fprintf(output, "%s;%s;\n", cur->name,
+                                                               node_child_value_string);
+                                       } else {
+                                               fprintf(output, "%s\n",
+                                                               node_child_value_string);
+                                       }
+                                       xmlFree(node_child_value_string);
+                               } else {
+                                       /* We don't want to print non-final element */
+                                       if (node_exist) {
+                                               result = true;
+                                       } else {
+                                               fprintf(stderr, "ERR:%s\n",
+                                                               "Xpath expression return non-final xml element");
+                                               ret = -1;
+                                               goto end;
+                                       }
+                               }
+                       } else {
+                               if (node_exist) {
+                                       result = true;
+                               } else {
+                                       /* We don't want to print non-final element */
+                                       fprintf(stderr, "ERR:%s\n",
+                                                       "Xpath expression return non-final xml element");
+                                       ret = -1;
+                                       goto end;
+                               }
+                       }
+
+               } else {
+                       cur = nodes->nodeTab[i];
+                       if (node_exist) {
+                               result = true;
+                       } else if (opt_verbose) {
+                               fprintf(output, "%s;%s;\n", cur->parent->name, cur->content);
+                       } else {
+                               fprintf(output, "%s\n", cur->content);
+                       }
+               }
+       }
+       /* Command Success */
+       ret = 0;
+
+end:
+       return ret;
+}
+
+static int register_lttng_namespace(xmlXPathContextPtr xpathCtx)
+{
+       int ret;
+       xmlChar *prefix;
+       xmlChar *ns = NULL;
+
+       prefix = xmlCharStrdup("lttng");
+       if (!prefix) {
+               ret = -1;
+               goto end;
+       }
+
+       ns = xmlCharStrdup(DEFAULT_LTTNG_MI_NAMESPACE);
+       if (!ns) {
+               ret = -1;
+               goto end;
+       }
+
+       ret = xmlXPathRegisterNs(xpathCtx, prefix, ns);
+end:
+       xmlFree(prefix);
+       xmlFree(ns);
+       return ret;
+}
+
+/*
+ * Extract element corresponding to xpath
+ * xml_path     The path to the xml file
+ * xpath:       The xpath to evaluate.
+ *
+ * Evaluate an xpath expression onto an xml file.
+ * and print the result one by line.
+ *
+ * Returns 0 on success and a negative value otherwise.
+ */
+static int extract_xpath(const char *xml_path, const xmlChar *xpath)
+{
+       int ret;
+       xmlDocPtr doc = NULL;
+       xmlXPathContextPtr xpathCtx = NULL;
+       xmlXPathObjectPtr xpathObj = NULL;
+
+       assert(xml_path);
+       assert(xpath);
+
+       /* Parse the xml file */
+       doc = xmlParseFile(xml_path);
+       if (!doc) {
+               fprintf(stderr, "ERR parsing: xml file invalid \"%s\"\n", xml_path);
+               return -1;
+       }
+
+       /* Initialize a xpath context */
+       xpathCtx = xmlXPathNewContext(doc);
+       if (!xpathCtx) {
+               fprintf(stderr, "ERR: XPath context invalid\n");
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       /* Register the LTTng MI namespace */
+       ret = register_lttng_namespace(xpathCtx);
+       if (ret) {
+               fprintf(stderr, "ERR: Could not register lttng namespace\n");
+               xmlXPathFreeContext(xpathCtx);
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       /* Evaluate xpath expression */
+       xpathObj = xmlXPathEvalExpression(xpath, xpathCtx);
+       if (!xpathObj) {
+               fprintf(stderr, "ERR: invalid xpath expression \"%s\"\n", xpath);
+               xmlXPathFreeContext(xpathCtx);
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       /* Print results */
+       if (print_xpath_nodes(doc, xpathObj->nodesetval, stdout)) {
+               xmlXPathFreeObject(xpathObj);
+               xmlXPathFreeContext(xpathCtx);
+               xmlFreeDoc(doc);
+               return -1;
+       }
+       if (node_exist && result) {
+               fprintf(stdout, "true\n");
+       }
+
+       /* Cleanup */
+       xmlXPathFreeObject(xpathObj);
+       xmlXPathFreeContext(xpathCtx);
+       xmlFreeDoc(doc);
+
+       return 0;
+}
+
+int main(int argc, char **argv)
+{
+       int opt;
+
+       /* Parse command line and process file */
+       while ((opt = getopt(argc, argv, "ve")) != -1) {
+               switch (opt) {
+               case 'v':
+                       opt_verbose = 1;
+                       break;
+               case 'e':
+                       node_exist = 1;
+                       break;
+               default:
+                       abort();
+               }
+       }
+
+       if (!(optind + 1 < argc)) {
+               fprintf(stderr, "ERR:%s\n", "Arguments missing");
+               return -1;
+       }
+
+       /* Init libxml */
+       xmlInitParser();
+       xmlKeepBlanksDefault(0);
+       if (access(argv[optind], F_OK)) {
+               fprintf(stderr, "ERR:%s\n", "Xml path not valid");
+               return -1;
+       }
+       /* Do the main job */
+       if (extract_xpath(argv[optind], (xmlChar *)argv[optind+1])) {
+               return -1;
+       }
+
+       /* Shutdown libxml */
+       xmlCleanupParser();
+
+       return 0;
+}
+
+#else
+int main(void)
+{
+       fprintf(stderr, "XPath support not compiled in\n");
+       return -1;
+}
+#endif
diff --git a/tests/utils/xml-utils/validate_xml.c b/tests/utils/xml-utils/validate_xml.c
new file mode 100644 (file)
index 0000000..eafe8b7
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2014 Jonathan Rajotte <jonathan.r.julien@gmail.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ */
+
+ /*
+  * This script validate and xml from an xsd.
+  * argv[1] Path of the xsd
+  * argv[2] Path to the XML to be validated
+  */
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <libxml/xmlschemas.h>
+#include <libxml/parser.h>
+
+#include <lttng/lttng-error.h>
+
+struct validation_ctx {
+       xmlSchemaParserCtxtPtr parser_ctx;
+       xmlSchemaPtr schema;
+       xmlSchemaValidCtxtPtr schema_validation_ctx;
+};
+
+enum command_err_code {
+       CMD_SUCCESS = 0,
+       CMD_ERROR
+};
+
+static
+void xml_error_handler(void *ctx, const char *format, ...)
+{
+       char *err_msg;
+       va_list args;
+       int ret;
+
+       va_start(args, format);
+       ret = vasprintf(&err_msg, format, args);
+       va_end(args);
+       if (ret == -1) {
+               fprintf(stderr, "ERR: %s\n",
+                               "String allocation failed in xml error handle");
+               return;
+       }
+
+       fprintf(stderr, "XML Error: %s\n", err_msg);
+       free(err_msg);
+}
+
+static
+void fini_validation_ctx(
+       struct validation_ctx *ctx)
+{
+       if (ctx->parser_ctx) {
+               xmlSchemaFreeParserCtxt(ctx->parser_ctx);
+       }
+
+       if (ctx->schema) {
+               xmlSchemaFree(ctx->schema);
+       }
+
+       if (ctx->schema_validation_ctx) {
+               xmlSchemaFreeValidCtxt(ctx->schema_validation_ctx);
+       }
+
+       memset(ctx, 0, sizeof(struct validation_ctx));
+}
+
+static
+int init_validation_ctx(
+       struct validation_ctx *ctx, char *xsd_path)
+{
+       int ret;
+
+       if (!xsd_path) {
+               ret = -LTTNG_ERR_NOMEM;
+               goto end;
+       }
+
+       ctx->parser_ctx = xmlSchemaNewParserCtxt(xsd_path);
+       if (!ctx->parser_ctx) {
+               ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
+               goto end;
+       }
+       xmlSchemaSetParserErrors(ctx->parser_ctx, xml_error_handler,
+               xml_error_handler, NULL);
+
+       ctx->schema = xmlSchemaParse(ctx->parser_ctx);
+       if (!ctx->schema) {
+               ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
+               goto end;
+       }
+
+       ctx->schema_validation_ctx = xmlSchemaNewValidCtxt(ctx->schema);
+       if (!ctx->schema_validation_ctx) {
+               ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
+               goto end;
+       }
+
+       xmlSchemaSetValidErrors(ctx->schema_validation_ctx, xml_error_handler,
+                       xml_error_handler, NULL);
+       ret = 0;
+
+end:
+       if (ret) {
+               fini_validation_ctx(ctx);
+       }
+       return ret;
+}
+
+static int validate_xml(const char *xml_file_path, struct validation_ctx *ctx)
+{
+       int ret;
+       xmlDocPtr doc = NULL;
+
+       assert(xml_file_path);
+       assert(ctx);
+
+       /* Open the document */
+       doc = xmlParseFile(xml_file_path);
+       if (!doc) {
+               ret = LTTNG_ERR_MI_IO_FAIL;
+               goto end;
+       }
+
+       /* Validate against the validation ctx (xsd) */
+       ret = xmlSchemaValidateDoc(ctx->schema_validation_ctx, doc);
+       if (ret) {
+               fprintf(stderr, "ERR: %s\n", "XML is not valid againt provided XSD");
+               ret = CMD_ERROR;
+               goto end;
+       }
+
+       ret = CMD_SUCCESS;
+end:
+       return ret;
+
+
+}
+int main(int argc, char **argv, char *env[])
+{
+       int ret;
+       struct validation_ctx ctx = { 0 };
+
+       /* Check if we have all argument */
+       if (argc < 3) {
+               fprintf(stderr, "ERR: %s\n", "Missing arguments");
+               ret = CMD_ERROR;
+               goto end;
+       }
+
+       /* Check if xsd file exist */
+       ret = access(argv[1], F_OK);
+       if (ret < 0) {
+               fprintf(stderr, "ERR: %s\n", "Xsd path not valid");
+               goto end;
+       }
+
+       /* Check if xml to validate exist */
+       ret = access(argv[2], F_OK);
+       if (ret < 0) {
+               fprintf(stderr, "ERR: %s\n", "XML path not valid");
+               goto end;
+       }
+
+       /* initialize the validation ctx */
+       ret = init_validation_ctx(&ctx, argv[1]);
+       if (ret) {
+               goto end;
+       }
+
+       ret = validate_xml(argv[2], &ctx);
+
+       fini_validation_ctx(&ctx);
+
+end:
+       return ret;
+}
This page took 0.043581 seconds and 5 git commands to generate.