Rename C++ header files to .hpp
[lttng-tools.git] / tests / utils / xml-utils / validate_xml.cpp
1 /*
2 * Copyright (C) 2014 EfficiOS Inc.
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
8 /*
9 * This script validate and xml from an xsd.
10 * argv[1] Path of the xsd
11 * argv[2] Path to the XML to be validated
12 */
13
14 #include <ctype.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <inttypes.h>
19 #include <dirent.h>
20 #include <unistd.h>
21 #include <sys/types.h>
22 #include <sys/stat.h>
23
24 #include <libxml/xmlschemas.h>
25 #include <libxml/parser.h>
26
27 #include <lttng/lttng-error.h>
28 #include <common/macros.hpp>
29
30 struct validation_ctx {
31 xmlSchemaParserCtxtPtr parser_ctx;
32 xmlSchemaPtr schema;
33 xmlSchemaValidCtxtPtr schema_validation_ctx;
34 };
35
36 enum command_err_code {
37 CMD_SUCCESS = 0,
38 CMD_ERROR
39 };
40
41 static ATTR_FORMAT_PRINTF(2, 3)
42 void xml_error_handler(void *ctx __attribute__((unused)),
43 const char *format, ...)
44 {
45 char *err_msg;
46 va_list args;
47 int ret;
48
49 va_start(args, format);
50 ret = vasprintf(&err_msg, format, args);
51 va_end(args);
52 if (ret == -1) {
53 fprintf(stderr, "ERR: %s\n",
54 "String allocation failed in xml error handle");
55 return;
56 }
57
58 fprintf(stderr, "XML Error: %s\n", err_msg);
59 free(err_msg);
60 }
61
62 static
63 void fini_validation_ctx(
64 struct validation_ctx *ctx)
65 {
66 if (ctx->parser_ctx) {
67 xmlSchemaFreeParserCtxt(ctx->parser_ctx);
68 }
69
70 if (ctx->schema) {
71 xmlSchemaFree(ctx->schema);
72 }
73
74 if (ctx->schema_validation_ctx) {
75 xmlSchemaFreeValidCtxt(ctx->schema_validation_ctx);
76 }
77
78 memset(ctx, 0, sizeof(struct validation_ctx));
79 }
80
81 static
82 int init_validation_ctx(
83 struct validation_ctx *ctx, char *xsd_path)
84 {
85 int ret;
86
87 if (!xsd_path) {
88 ret = -LTTNG_ERR_NOMEM;
89 goto end;
90 }
91
92 ctx->parser_ctx = xmlSchemaNewParserCtxt(xsd_path);
93 if (!ctx->parser_ctx) {
94 ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
95 goto end;
96 }
97 xmlSchemaSetParserErrors(ctx->parser_ctx, xml_error_handler,
98 xml_error_handler, NULL);
99
100 ctx->schema = xmlSchemaParse(ctx->parser_ctx);
101 if (!ctx->schema) {
102 ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
103 goto end;
104 }
105
106 ctx->schema_validation_ctx = xmlSchemaNewValidCtxt(ctx->schema);
107 if (!ctx->schema_validation_ctx) {
108 ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
109 goto end;
110 }
111
112 xmlSchemaSetValidErrors(ctx->schema_validation_ctx, xml_error_handler,
113 xml_error_handler, NULL);
114 ret = 0;
115
116 end:
117 if (ret) {
118 fini_validation_ctx(ctx);
119 }
120 return ret;
121 }
122
123 static int validate_xml(const char *xml_file_path, struct validation_ctx *ctx)
124 {
125 int ret;
126 xmlDocPtr doc = NULL;
127
128 LTTNG_ASSERT(xml_file_path);
129 LTTNG_ASSERT(ctx);
130
131 /* Open the document */
132 doc = xmlParseFile(xml_file_path);
133 if (!doc) {
134 ret = LTTNG_ERR_MI_IO_FAIL;
135 goto end;
136 }
137
138 /* Validate against the validation ctx (xsd) */
139 ret = xmlSchemaValidateDoc(ctx->schema_validation_ctx, doc);
140 if (ret) {
141 fprintf(stderr, "ERR: %s\n", "XML is not valid againt provided XSD");
142 ret = CMD_ERROR;
143 goto end;
144 }
145
146 ret = CMD_SUCCESS;
147 end:
148 return ret;
149
150
151 }
152 int main(int argc, char **argv)
153 {
154 int ret;
155 struct validation_ctx ctx = {};
156
157 /* Check if we have all argument */
158 if (argc < 3) {
159 fprintf(stderr, "ERR: %s\n", "Missing arguments");
160 ret = CMD_ERROR;
161 goto end;
162 }
163
164 /* Check if xsd file exist */
165 ret = access(argv[1], F_OK);
166 if (ret < 0) {
167 fprintf(stderr, "ERR: %s\n", "Xsd path not valid");
168 goto end;
169 }
170
171 /* Check if xml to validate exist */
172 ret = access(argv[2], F_OK);
173 if (ret < 0) {
174 fprintf(stderr, "ERR: %s\n", "XML path not valid");
175 goto end;
176 }
177
178 /* initialize the validation ctx */
179 ret = init_validation_ctx(&ctx, argv[1]);
180 if (ret) {
181 goto end;
182 }
183
184 ret = validate_xml(argv[2], &ctx);
185
186 fini_validation_ctx(&ctx);
187
188 end:
189 return ret;
190 }
This page took 0.03455 seconds and 5 git commands to generate.