blob: a3fe10a2b2b2320b80e5d4b5da5385e9348f21bd [file] [log] [blame]
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001/*
2 * xmllint.c : a small tester program for XML input.
3 *
4 * See Copyright for the status of this software.
5 *
Daniel Veillardc5d64342001-06-24 12:13:24 +00006 * daniel@veillard.com
Daniel Veillardce8b83b2000-04-05 18:38:42 +00007 */
8
Bjorn Reese70a9da52001-04-21 16:57:29 +00009#include "libxml.h"
Daniel Veillardce8b83b2000-04-05 18:38:42 +000010
Daniel Veillardce8b83b2000-04-05 18:38:42 +000011#include <string.h>
Daniel Veillardce8b83b2000-04-05 18:38:42 +000012#include <stdarg.h>
Daniel Veillard8a1b1852003-01-05 22:37:17 +000013#include <assert.h>
14
Daniel Veillarded472f32001-12-13 08:48:14 +000015#ifdef HAVE_SYS_TIME_H
Daniel Veillard48b2f892001-02-25 16:11:03 +000016#include <sys/time.h>
Daniel Veillarded472f32001-12-13 08:48:14 +000017#endif
Daniel Veillard01db67c2001-12-18 07:09:59 +000018#ifdef HAVE_TIME_H
19#include <time.h>
20#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +000021
Daniel Veillard90bc3712002-03-07 15:12:58 +000022#ifdef HAVE_SYS_TIMEB_H
23#include <sys/timeb.h>
24#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000025
26#ifdef HAVE_SYS_TYPES_H
27#include <sys/types.h>
28#endif
29#ifdef HAVE_SYS_STAT_H
30#include <sys/stat.h>
31#endif
32#ifdef HAVE_FCNTL_H
33#include <fcntl.h>
34#endif
35#ifdef HAVE_UNISTD_H
36#include <unistd.h>
37#endif
Daniel Veillard46e370e2000-07-21 20:32:03 +000038#ifdef HAVE_SYS_MMAN_H
39#include <sys/mman.h>
Daniel Veillard87b95392000-08-12 21:12:04 +000040/* seems needed for Solaris */
41#ifndef MAP_FAILED
42#define MAP_FAILED ((void *) -1)
43#endif
Daniel Veillard46e370e2000-07-21 20:32:03 +000044#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000045#ifdef HAVE_STDLIB_H
46#include <stdlib.h>
47#endif
48#ifdef HAVE_LIBREADLINE
49#include <readline/readline.h>
50#ifdef HAVE_LIBHISTORY
51#include <readline/history.h>
52#endif
53#endif
54
55#include <libxml/xmlmemory.h>
56#include <libxml/parser.h>
57#include <libxml/parserInternals.h>
58#include <libxml/HTMLparser.h>
59#include <libxml/HTMLtree.h>
60#include <libxml/tree.h>
61#include <libxml/xpath.h>
62#include <libxml/debugXML.h>
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +000063#include <libxml/xmlerror.h>
Daniel Veillard9e8bfae2000-11-06 16:43:11 +000064#ifdef LIBXML_XINCLUDE_ENABLED
65#include <libxml/xinclude.h>
66#endif
Daniel Veillard81418e32001-05-22 15:08:55 +000067#ifdef LIBXML_CATALOG_ENABLED
68#include <libxml/catalog.h>
69#endif
Daniel Veillard3c01b1d2001-10-17 15:58:35 +000070#include <libxml/globals.h>
Daniel Veillard7704fb12003-01-03 16:19:51 +000071#include <libxml/xmlreader.h>
Daniel Veillardd4501d72005-07-24 14:27:16 +000072#ifdef LIBXML_SCHEMATRON_ENABLED
73#include <libxml/schematron.h>
74#endif
Daniel Veillard71531f32003-02-05 13:19:53 +000075#ifdef LIBXML_SCHEMAS_ENABLED
76#include <libxml/relaxng.h>
Daniel Veillard75bb3bb2003-05-12 15:25:56 +000077#include <libxml/xmlschemas.h>
Daniel Veillard71531f32003-02-05 13:19:53 +000078#endif
Daniel Veillardb3de70c2003-12-02 22:32:15 +000079#ifdef LIBXML_PATTERN_ENABLED
80#include <libxml/pattern.h>
81#endif
Daniel Veillard6ebf3c42004-08-22 13:11:39 +000082#ifdef LIBXML_C14N_ENABLED
83#include <libxml/c14n.h>
84#endif
Daniel Veillarddab39b52006-10-16 23:22:10 +000085#ifdef LIBXML_OUTPUT_ENABLED
86#include <libxml/xmlsave.h>
87#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000088
Daniel Veillard3be27512003-01-26 19:49:04 +000089#ifndef XML_XML_DEFAULT_CATALOG
90#define XML_XML_DEFAULT_CATALOG "file:///etc/xml/catalog"
91#endif
92
William M. Brack8304d872004-06-08 13:29:32 +000093typedef enum {
94 XMLLINT_RETURN_OK = 0, /* No error */
Daniel Veillard1934b0c2009-10-07 10:25:06 +020095 XMLLINT_ERR_UNCLASS = 1, /* Unclassified */
96 XMLLINT_ERR_DTD = 2, /* Error in DTD */
97 XMLLINT_ERR_VALID = 3, /* Validation error */
98 XMLLINT_ERR_RDFILE = 4, /* CtxtReadFile error */
99 XMLLINT_ERR_SCHEMACOMP = 5, /* Schema compilation */
100 XMLLINT_ERR_OUT = 6, /* Error writing output */
101 XMLLINT_ERR_SCHEMAPAT = 7, /* Error in schema pattern */
102 XMLLINT_ERR_RDREGIS = 8, /* Error in Reader registration */
103 XMLLINT_ERR_MEM = 9, /* Out of memory error */
104 XMLLINT_ERR_XPATH = 10 /* XPath evaluation error */
William M. Brack8304d872004-06-08 13:29:32 +0000105} xmllintReturnCode;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000106#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000107static int shell = 0;
108static int debugent = 0;
109#endif
Daniel Veillard8326e732003-01-07 00:19:07 +0000110static int debug = 0;
Daniel Veillard87076042004-05-03 22:54:49 +0000111static int maxmem = 0;
Daniel Veillard652327a2003-09-29 18:02:38 +0000112#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000113static int copy = 0;
Daniel Veillard652327a2003-09-29 18:02:38 +0000114#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000115static int recovery = 0;
116static int noent = 0;
Daniel Veillardc62efc82011-05-16 16:03:50 +0800117static int noenc = 0;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +0000118static int noblanks = 0;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000119static int noout = 0;
120static int nowrap = 0;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +0000121#ifdef LIBXML_OUTPUT_ENABLED
122static int format = 0;
123static const char *output = NULL;
124static int compress = 0;
Daniel Veillarddab39b52006-10-16 23:22:10 +0000125static int oldout = 0;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +0000126#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard4432df22003-09-28 18:58:27 +0000127#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000128static int valid = 0;
129static int postvalid = 0;
Daniel Veillardcd429612000-10-11 15:57:05 +0000130static char * dtdvalid = NULL;
Daniel Veillard66f68e72003-08-18 16:39:51 +0000131static char * dtdvalidfpi = NULL;
Daniel Veillard4432df22003-09-28 18:58:27 +0000132#endif
Daniel Veillard71531f32003-02-05 13:19:53 +0000133#ifdef LIBXML_SCHEMAS_ENABLED
134static char * relaxng = NULL;
135static xmlRelaxNGPtr relaxngschemas = NULL;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +0000136static char * schema = NULL;
137static xmlSchemaPtr wxschemas = NULL;
Daniel Veillard71531f32003-02-05 13:19:53 +0000138#endif
Daniel Veillard8c6e6532005-09-08 21:39:47 +0000139#ifdef LIBXML_SCHEMATRON_ENABLED
Daniel Veillardd4501d72005-07-24 14:27:16 +0000140static char * schematron = NULL;
141static xmlSchematronPtr wxschematron = NULL;
142#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000143static int repeat = 0;
144static int insert = 0;
Daniel Veillard656ce942004-04-30 23:11:45 +0000145#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000146static int html = 0;
Daniel Veillard42fd4122003-11-04 08:47:48 +0000147static int xmlout = 0;
Daniel Veillard4432df22003-09-28 18:58:27 +0000148#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000149static int htmlout = 0;
Daniel Veillardf1121c42010-07-26 14:02:42 +0200150#if defined(LIBXML_HTML_ENABLED)
151static int nodefdtd = 0;
152#endif
Daniel Veillard73b013f2003-09-30 12:36:01 +0000153#ifdef LIBXML_PUSH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000154static int push = 0;
Daniel Veillard1abd2212012-10-25 15:37:50 +0800155static int pushsize = 4096;
Daniel Veillard73b013f2003-09-30 12:36:01 +0000156#endif /* LIBXML_PUSH_ENABLED */
Daniel Richard G5706b6d2012-08-06 11:32:54 +0800157#ifdef HAVE_MMAP
Daniel Veillard46e370e2000-07-21 20:32:03 +0000158static int memory = 0;
159#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +0000160static int testIO = 0;
Daniel Veillardbe803962000-06-28 23:40:59 +0000161static char *encoding = NULL;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000162#ifdef LIBXML_XINCLUDE_ENABLED
163static int xinclude = 0;
164#endif
Daniel Veillard48da9102001-08-07 01:10:10 +0000165static int dtdattrs = 0;
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000166static int loaddtd = 0;
William M. Brack8304d872004-06-08 13:29:32 +0000167static xmllintReturnCode progresult = XMLLINT_RETURN_OK;
Haibo Huang735158e2021-02-23 17:48:08 -0800168static int quiet = 0;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000169static int timing = 0;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000170static int generate = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000171static int dropdtd = 0;
Daniel Veillarde2940dd2001-08-22 00:06:49 +0000172#ifdef LIBXML_CATALOG_ENABLED
173static int catalogs = 0;
174static int nocatalogs = 0;
175#endif
Daniel Veillard25048d82004-08-14 22:37:54 +0000176#ifdef LIBXML_C14N_ENABLED
177static int canonical = 0;
Aleksey Sanin83868242009-07-09 10:26:22 +0200178static int canonical_11 = 0;
Aleksey Sanin2650df12005-06-06 17:16:50 +0000179static int exc_canonical = 0;
Daniel Veillard25048d82004-08-14 22:37:54 +0000180#endif
Daniel Veillard81273902003-09-30 00:43:48 +0000181#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +0000182static int stream = 0;
Daniel Veillard7899c5c2003-11-03 12:31:38 +0000183static int walker = 0;
Haibo Huangcfd91dc2020-07-30 23:01:33 -0700184#ifdef LIBXML_PATTERN_ENABLED
185static const char *pattern = NULL;
186static xmlPatternPtr patternc = NULL;
187static xmlStreamCtxtPtr patstream = NULL;
188#endif
Daniel Veillard81273902003-09-30 00:43:48 +0000189#endif /* LIBXML_READER_ENABLED */
Daniel Veillard8a1b1852003-01-05 22:37:17 +0000190static int chkregister = 0;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +0000191static int nbregister = 0;
Daniel Veillard81273902003-09-30 00:43:48 +0000192#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +0000193static int sax1 = 0;
Daniel Veillard81273902003-09-30 00:43:48 +0000194#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillard1934b0c2009-10-07 10:25:06 +0200195#ifdef LIBXML_XPATH_ENABLED
196static const char *xpathquery = NULL;
197#endif
Daniel Veillard968a03a2012-08-13 12:41:33 +0800198static int options = XML_PARSE_COMPACT | XML_PARSE_BIG_LINES;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000199static int sax = 0;
Daniel Veillard7e5c3f42008-07-29 16:12:31 +0000200static int oldxml10 = 0;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +0000201
Daniel Veillard87076042004-05-03 22:54:49 +0000202/************************************************************************
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000203 * *
204 * Entity loading control and customization. *
205 * *
206 ************************************************************************/
207#define MAX_PATHS 64
Daniel Veillarded121382007-04-17 12:33:19 +0000208#ifdef _WIN32
209# define PATH_SEPARATOR ';'
210#else
211# define PATH_SEPARATOR ':'
212#endif
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000213static xmlChar *paths[MAX_PATHS + 1];
214static int nbpaths = 0;
215static int load_trace = 0;
216
217static
218void parsePath(const xmlChar *path) {
219 const xmlChar *cur;
220
221 if (path == NULL)
222 return;
223 while (*path != 0) {
224 if (nbpaths >= MAX_PATHS) {
225 fprintf(stderr, "MAX_PATHS reached: too many paths\n");
226 return;
227 }
228 cur = path;
Daniel Veillarded121382007-04-17 12:33:19 +0000229 while ((*cur == ' ') || (*cur == PATH_SEPARATOR))
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000230 cur++;
231 path = cur;
Daniel Veillarded121382007-04-17 12:33:19 +0000232 while ((*cur != 0) && (*cur != ' ') && (*cur != PATH_SEPARATOR))
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000233 cur++;
234 if (cur != path) {
235 paths[nbpaths] = xmlStrndup(path, cur - path);
236 if (paths[nbpaths] != NULL)
237 nbpaths++;
238 path = cur;
239 }
240 }
241}
242
Daniel Veillard24505b02005-07-28 23:49:35 +0000243static xmlExternalEntityLoader defaultEntityLoader = NULL;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000244
Daniel Veillardf1edb102009-08-10 14:43:18 +0200245static xmlParserInputPtr
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000246xmllintExternalEntityLoader(const char *URL, const char *ID,
247 xmlParserCtxtPtr ctxt) {
248 xmlParserInputPtr ret;
249 warningSAXFunc warning = NULL;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000250 errorSAXFunc err = NULL;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000251
252 int i;
253 const char *lastsegment = URL;
254 const char *iter = URL;
255
Daniel Veillard5608b172008-01-11 06:53:15 +0000256 if ((nbpaths > 0) && (iter != NULL)) {
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000257 while (*iter != 0) {
258 if (*iter == '/')
259 lastsegment = iter + 1;
260 iter++;
261 }
262 }
263
264 if ((ctxt != NULL) && (ctxt->sax != NULL)) {
265 warning = ctxt->sax->warning;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000266 err = ctxt->sax->error;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000267 ctxt->sax->warning = NULL;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000268 ctxt->sax->error = NULL;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000269 }
270
271 if (defaultEntityLoader != NULL) {
272 ret = defaultEntityLoader(URL, ID, ctxt);
273 if (ret != NULL) {
274 if (warning != NULL)
275 ctxt->sax->warning = warning;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000276 if (err != NULL)
277 ctxt->sax->error = err;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000278 if (load_trace) {
279 fprintf \
280 (stderr,
281 "Loaded URL=\"%s\" ID=\"%s\"\n",
282 URL ? URL : "(null)",
283 ID ? ID : "(null)");
284 }
285 return(ret);
286 }
287 }
288 for (i = 0;i < nbpaths;i++) {
289 xmlChar *newURL;
290
291 newURL = xmlStrdup((const xmlChar *) paths[i]);
292 newURL = xmlStrcat(newURL, (const xmlChar *) "/");
293 newURL = xmlStrcat(newURL, (const xmlChar *) lastsegment);
294 if (newURL != NULL) {
295 ret = defaultEntityLoader((const char *)newURL, ID, ctxt);
296 if (ret != NULL) {
297 if (warning != NULL)
298 ctxt->sax->warning = warning;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000299 if (err != NULL)
300 ctxt->sax->error = err;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000301 if (load_trace) {
302 fprintf \
Daniel Veillardf1edb102009-08-10 14:43:18 +0200303 (stderr,
304 "Loaded URL=\"%s\" ID=\"%s\"\n",
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000305 newURL,
Daniel Veillardf1edb102009-08-10 14:43:18 +0200306 ID ? ID : "(null)");
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000307 }
308 xmlFree(newURL);
309 return(ret);
310 }
311 xmlFree(newURL);
312 }
313 }
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000314 if (err != NULL)
315 ctxt->sax->error = err;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000316 if (warning != NULL) {
317 ctxt->sax->warning = warning;
318 if (URL != NULL)
319 warning(ctxt, "failed to load external entity \"%s\"\n", URL);
320 else if (ID != NULL)
321 warning(ctxt, "failed to load external entity \"%s\"\n", ID);
322 }
323 return(NULL);
324}
325/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +0200326 * *
Daniel Veillard87076042004-05-03 22:54:49 +0000327 * Memory allocation consumption debugging *
Daniel Veillardf1edb102009-08-10 14:43:18 +0200328 * *
Daniel Veillard87076042004-05-03 22:54:49 +0000329 ************************************************************************/
330
Daniel Veillard3af3b592004-05-05 19:22:30 +0000331static void
332OOM(void)
333{
Daniel Veillard87076042004-05-03 22:54:49 +0000334 fprintf(stderr, "Ran out of memory needs > %d bytes\n", maxmem);
William M. Brack8304d872004-06-08 13:29:32 +0000335 progresult = XMLLINT_ERR_MEM;
Daniel Veillard87076042004-05-03 22:54:49 +0000336}
337
Daniel Veillard3af3b592004-05-05 19:22:30 +0000338static void
339myFreeFunc(void *mem)
340{
Daniel Veillard87076042004-05-03 22:54:49 +0000341 xmlMemFree(mem);
342}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000343static void *
344myMallocFunc(size_t size)
345{
Daniel Veillard87076042004-05-03 22:54:49 +0000346 void *ret;
347
348 ret = xmlMemMalloc(size);
349 if (ret != NULL) {
350 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000351 OOM();
352 xmlMemFree(ret);
353 return (NULL);
354 }
Daniel Veillard87076042004-05-03 22:54:49 +0000355 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000356 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000357}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000358static void *
359myReallocFunc(void *mem, size_t size)
360{
Daniel Veillard87076042004-05-03 22:54:49 +0000361 void *ret;
362
363 ret = xmlMemRealloc(mem, size);
364 if (ret != NULL) {
365 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000366 OOM();
367 xmlMemFree(ret);
368 return (NULL);
369 }
Daniel Veillard87076042004-05-03 22:54:49 +0000370 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000371 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000372}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000373static char *
374myStrdupFunc(const char *str)
375{
Daniel Veillard87076042004-05-03 22:54:49 +0000376 char *ret;
377
378 ret = xmlMemoryStrdup(str);
379 if (ret != NULL) {
380 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000381 OOM();
382 xmlFree(ret);
383 return (NULL);
384 }
Daniel Veillard87076042004-05-03 22:54:49 +0000385 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000386 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000387}
Daniel Veillard87076042004-05-03 22:54:49 +0000388/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +0200389 * *
Daniel Veillard87076042004-05-03 22:54:49 +0000390 * Internal timing routines to remove the necessity to have *
391 * unix-specific function calls. *
Daniel Veillardf1edb102009-08-10 14:43:18 +0200392 * *
Daniel Veillard87076042004-05-03 22:54:49 +0000393 ************************************************************************/
Daniel Veillard01db67c2001-12-18 07:09:59 +0000394
Daniel Veillardf1edb102009-08-10 14:43:18 +0200395#ifndef HAVE_GETTIMEOFDAY
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000396#ifdef HAVE_SYS_TIMEB_H
397#ifdef HAVE_SYS_TIME_H
398#ifdef HAVE_FTIME
399
Daniel Veillard01c13b52002-12-10 15:19:08 +0000400static int
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000401my_gettimeofday(struct timeval *tvp, void *tzp)
402{
403 struct timeb timebuffer;
404
405 ftime(&timebuffer);
406 if (tvp) {
407 tvp->tv_sec = timebuffer.time;
408 tvp->tv_usec = timebuffer.millitm * 1000L;
409 }
410 return (0);
411}
412#define HAVE_GETTIMEOFDAY 1
413#define gettimeofday my_gettimeofday
414
415#endif /* HAVE_FTIME */
416#endif /* HAVE_SYS_TIME_H */
417#endif /* HAVE_SYS_TIMEB_H */
418#endif /* !HAVE_GETTIMEOFDAY */
419
Daniel Veillard01db67c2001-12-18 07:09:59 +0000420#if defined(HAVE_GETTIMEOFDAY)
421static struct timeval begin, end;
422
423/*
424 * startTimer: call where you want to start timing
425 */
426static void
427startTimer(void)
428{
429 gettimeofday(&begin, NULL);
430}
431
432/*
433 * endTimer: call where you want to stop timing and to print out a
434 * message about the timing performed; format is a printf
435 * type argument
436 */
David Kilzer4472c3a2016-05-13 15:13:17 +0800437static void XMLCDECL LIBXML_ATTR_FORMAT(1,2)
Daniel Veillard118aed72002-09-24 14:13:13 +0000438endTimer(const char *fmt, ...)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000439{
440 long msec;
441 va_list ap;
442
443 gettimeofday(&end, NULL);
444 msec = end.tv_sec - begin.tv_sec;
445 msec *= 1000;
446 msec += (end.tv_usec - begin.tv_usec) / 1000;
447
448#ifndef HAVE_STDARG_H
449#error "endTimer required stdarg functions"
450#endif
Daniel Veillard118aed72002-09-24 14:13:13 +0000451 va_start(ap, fmt);
452 vfprintf(stderr, fmt, ap);
Daniel Veillard01db67c2001-12-18 07:09:59 +0000453 va_end(ap);
454
455 fprintf(stderr, " took %ld ms\n", msec);
456}
457#elif defined(HAVE_TIME_H)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000458/*
459 * No gettimeofday function, so we have to make do with calling clock.
460 * This is obviously less accurate, but there's little we can do about
461 * that.
462 */
Daniel Veillard90bc3712002-03-07 15:12:58 +0000463#ifndef CLOCKS_PER_SEC
464#define CLOCKS_PER_SEC 100
465#endif
Daniel Veillard01db67c2001-12-18 07:09:59 +0000466
467static clock_t begin, end;
468static void
469startTimer(void)
470{
471 begin = clock();
472}
David Kilzer4472c3a2016-05-13 15:13:17 +0800473static void XMLCDECL LIBXML_ATTR_FORMAT(1,2)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000474endTimer(const char *fmt, ...)
475{
476 long msec;
477 va_list ap;
478
479 end = clock();
480 msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
481
482#ifndef HAVE_STDARG_H
483#error "endTimer required stdarg functions"
484#endif
485 va_start(ap, fmt);
486 vfprintf(stderr, fmt, ap);
487 va_end(ap);
488 fprintf(stderr, " took %ld ms\n", msec);
489}
490#else
491
492/*
493 * We don't have a gettimeofday or time.h, so we just don't do timing
494 */
495static void
496startTimer(void)
497{
498 /*
499 * Do nothing
500 */
501}
David Kilzer4472c3a2016-05-13 15:13:17 +0800502static void XMLCDECL LIBXML_ATTR_FORMAT(1,2)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000503endTimer(char *format, ...)
504{
505 /*
506 * We cannot do anything because we don't have a timing function
507 */
508#ifdef HAVE_STDARG_H
Patrick R. Gansterer023206f2012-05-10 22:17:51 +0800509 va_list ap;
Daniel Veillard01db67c2001-12-18 07:09:59 +0000510 va_start(ap, format);
511 vfprintf(stderr, format, ap);
512 va_end(ap);
Patrick R. Gansterer023206f2012-05-10 22:17:51 +0800513 fprintf(stderr, " was not timed\n");
Daniel Veillard01db67c2001-12-18 07:09:59 +0000514#else
515 /* We don't have gettimeofday, time or stdarg.h, what crazy world is
516 * this ?!
517 */
518#endif
519}
520#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000521/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +0200522 * *
Haibo Huangcfd91dc2020-07-30 23:01:33 -0700523 * HTML output *
Daniel Veillardf1edb102009-08-10 14:43:18 +0200524 * *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000525 ************************************************************************/
Daniel Veillard24505b02005-07-28 23:49:35 +0000526static char buffer[50000];
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000527
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000528static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000529xmlHTMLEncodeSend(void) {
530 char *result;
531
Haibo Huangf0a546b2020-09-01 20:28:19 -0700532 /*
533 * xmlEncodeEntitiesReentrant assumes valid UTF-8, but the buffer might
534 * end with a truncated UTF-8 sequence. This is a hack to at least avoid
535 * an out-of-bounds read.
536 */
537 memset(&buffer[sizeof(buffer)-4], 0, 4);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000538 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
539 if (result) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000540 xmlGenericError(xmlGenericErrorContext, "%s", result);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000541 xmlFree(result);
542 }
543 buffer[0] = 0;
544}
545
546/**
547 * xmlHTMLPrintFileInfo:
548 * @input: an xmlParserInputPtr input
Daniel Veillardf1edb102009-08-10 14:43:18 +0200549 *
Haibo Huangcfd91dc2020-07-30 23:01:33 -0700550 * Displays the associated file and line information for the current input
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000551 */
552
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000553static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000554xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000555 int len;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000556 xmlGenericError(xmlGenericErrorContext, "<p>");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000557
558 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000559 if (input != NULL) {
560 if (input->filename) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000561 snprintf(&buffer[len], sizeof(buffer) - len, "%s:%d: ", input->filename,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000562 input->line);
563 } else {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000564 snprintf(&buffer[len], sizeof(buffer) - len, "Entity: line %d: ", input->line);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000565 }
566 }
567 xmlHTMLEncodeSend();
568}
569
570/**
571 * xmlHTMLPrintFileContext:
572 * @input: an xmlParserInputPtr input
Daniel Veillardf1edb102009-08-10 14:43:18 +0200573 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000574 * Displays current context within the input content for error tracking
575 */
576
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000577static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000578xmlHTMLPrintFileContext(xmlParserInputPtr input) {
579 const xmlChar *cur, *base;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000580 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000581 int n;
582
583 if (input == NULL) return;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000584 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000585 cur = input->cur;
586 base = input->base;
587 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
588 cur--;
589 }
590 n = 0;
591 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
592 cur--;
593 if ((*cur == '\n') || (*cur == '\r')) cur++;
594 base = cur;
595 n = 0;
596 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000597 len = strlen(buffer);
Daniel Veillardf1edb102009-08-10 14:43:18 +0200598 snprintf(&buffer[len], sizeof(buffer) - len, "%c",
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000599 (unsigned char) *cur++);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000600 n++;
601 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000602 len = strlen(buffer);
603 snprintf(&buffer[len], sizeof(buffer) - len, "\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000604 cur = input->cur;
605 while ((*cur == '\n') || (*cur == '\r'))
606 cur--;
607 n = 0;
608 while ((cur != base) && (n++ < 80)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000609 len = strlen(buffer);
610 snprintf(&buffer[len], sizeof(buffer) - len, " ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000611 base++;
612 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000613 len = strlen(buffer);
614 snprintf(&buffer[len], sizeof(buffer) - len, "^\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000615 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000616 xmlGenericError(xmlGenericErrorContext, "</pre>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000617}
618
619/**
620 * xmlHTMLError:
621 * @ctx: an XML parser context
622 * @msg: the message to display/transmit
623 * @...: extra parameters for the message display
Daniel Veillardf1edb102009-08-10 14:43:18 +0200624 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000625 * Display and format an error messages, gives file, line, position and
626 * extra parameters.
627 */
David Kilzer4472c3a2016-05-13 15:13:17 +0800628static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000629xmlHTMLError(void *ctx, const char *msg, ...)
630{
631 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
632 xmlParserInputPtr input;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000633 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000634 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000635
636 buffer[0] = 0;
637 input = ctxt->input;
638 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000639 input = ctxt->inputTab[ctxt->inputNr - 2];
640 }
Daniel Veillardf1edb102009-08-10 14:43:18 +0200641
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000642 xmlHTMLPrintFileInfo(input);
643
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000644 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000645 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000646 len = strlen(buffer);
647 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000648 va_end(args);
649 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000650 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000651
652 xmlHTMLPrintFileContext(input);
653 xmlHTMLEncodeSend();
654}
655
656/**
657 * xmlHTMLWarning:
658 * @ctx: an XML parser context
659 * @msg: the message to display/transmit
660 * @...: extra parameters for the message display
Daniel Veillardf1edb102009-08-10 14:43:18 +0200661 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000662 * Display and format a warning messages, gives file, line, position and
663 * extra parameters.
664 */
David Kilzer4472c3a2016-05-13 15:13:17 +0800665static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000666xmlHTMLWarning(void *ctx, const char *msg, ...)
667{
668 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
669 xmlParserInputPtr input;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000670 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000671 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000672
673 buffer[0] = 0;
674 input = ctxt->input;
675 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000676 input = ctxt->inputTab[ctxt->inputNr - 2];
677 }
Daniel Veillardf1edb102009-08-10 14:43:18 +0200678
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000679
680 xmlHTMLPrintFileInfo(input);
Daniel Veillardf1edb102009-08-10 14:43:18 +0200681
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000682 xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000683 va_start(args, msg);
Daniel Veillardf1edb102009-08-10 14:43:18 +0200684 len = strlen(buffer);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000685 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000686 va_end(args);
687 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000688 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000689
690 xmlHTMLPrintFileContext(input);
691 xmlHTMLEncodeSend();
692}
693
694/**
695 * xmlHTMLValidityError:
696 * @ctx: an XML parser context
697 * @msg: the message to display/transmit
698 * @...: extra parameters for the message display
Daniel Veillardf1edb102009-08-10 14:43:18 +0200699 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000700 * Display and format an validity error messages, gives file,
701 * line, position and extra parameters.
702 */
David Kilzer4472c3a2016-05-13 15:13:17 +0800703static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000704xmlHTMLValidityError(void *ctx, const char *msg, ...)
705{
706 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
707 xmlParserInputPtr input;
708 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000709 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000710
711 buffer[0] = 0;
712 input = ctxt->input;
713 if ((input->filename == NULL) && (ctxt->inputNr > 1))
714 input = ctxt->inputTab[ctxt->inputNr - 2];
Daniel Veillardf1edb102009-08-10 14:43:18 +0200715
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000716 xmlHTMLPrintFileInfo(input);
717
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000718 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000719 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000720 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000721 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000722 va_end(args);
723 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000724 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000725
726 xmlHTMLPrintFileContext(input);
727 xmlHTMLEncodeSend();
Daniel Veillard9fcb4912005-03-16 12:57:31 +0000728 progresult = XMLLINT_ERR_VALID;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000729}
730
731/**
732 * xmlHTMLValidityWarning:
733 * @ctx: an XML parser context
734 * @msg: the message to display/transmit
735 * @...: extra parameters for the message display
Daniel Veillardf1edb102009-08-10 14:43:18 +0200736 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000737 * Display and format a validity warning messages, gives file, line,
738 * position and extra parameters.
739 */
David Kilzer4472c3a2016-05-13 15:13:17 +0800740static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000741xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
742{
743 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
744 xmlParserInputPtr input;
745 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000746 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000747
748 buffer[0] = 0;
749 input = ctxt->input;
750 if ((input->filename == NULL) && (ctxt->inputNr > 1))
751 input = ctxt->inputTab[ctxt->inputNr - 2];
752
753 xmlHTMLPrintFileInfo(input);
Daniel Veillardf1edb102009-08-10 14:43:18 +0200754
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000755 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000756 va_start(args, msg);
Daniel Veillardf1edb102009-08-10 14:43:18 +0200757 len = strlen(buffer);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000758 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000759 va_end(args);
760 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000761 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000762
763 xmlHTMLPrintFileContext(input);
764 xmlHTMLEncodeSend();
765}
766
767/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +0200768 * *
769 * Shell Interface *
770 * *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000771 ************************************************************************/
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000772#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000773#ifdef LIBXML_XPATH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000774/**
775 * xmlShellReadline:
776 * @prompt: the prompt value
777 *
778 * Read a string
Daniel Veillardf1edb102009-08-10 14:43:18 +0200779 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000780 * Returns a pointer to it or NULL on EOF the caller is expected to
781 * free the returned string.
782 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000783static char *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000784xmlShellReadline(char *prompt) {
785#ifdef HAVE_LIBREADLINE
786 char *line_read;
787
788 /* Get a line from the user. */
789 line_read = readline (prompt);
790
791 /* If the line has any text in it, save it on the history. */
792 if (line_read && *line_read)
793 add_history (line_read);
794
795 return (line_read);
796#else
797 char line_read[501];
Daniel Veillard29e43992001-12-13 22:21:58 +0000798 char *ret;
799 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000800
801 if (prompt != NULL)
802 fprintf(stdout, "%s", prompt);
Patrick Monnerat11e805d2015-04-17 17:02:59 +0200803 fflush(stdout);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000804 if (!fgets(line_read, 500, stdin))
805 return(NULL);
806 line_read[500] = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000807 len = strlen(line_read);
808 ret = (char *) malloc(len + 1);
809 if (ret != NULL) {
810 memcpy (ret, line_read, len + 1);
811 }
812 return(ret);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000813#endif
814}
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000815#endif /* LIBXML_XPATH_ENABLED */
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000816#endif /* LIBXML_DEBUG_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000817
818/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +0200819 * *
820 * I/O Interfaces *
821 * *
Daniel Veillard5e873c42000-04-12 13:27:38 +0000822 ************************************************************************/
823
Nick Wellnhofer86615e42017-11-09 17:47:47 +0100824static int myRead(void *f, char *buf, int len) {
825 return(fread(buf, 1, len, (FILE *) f));
Daniel Veillard5e873c42000-04-12 13:27:38 +0000826}
Nick Wellnhofer86615e42017-11-09 17:47:47 +0100827static int myClose(void *context) {
828 FILE *f = (FILE *) context;
829 if (f == stdin)
830 return(0);
831 return(fclose(f));
Daniel Veillard5e873c42000-04-12 13:27:38 +0000832}
833
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000834/************************************************************************
835 * *
Daniel Veillardf1edb102009-08-10 14:43:18 +0200836 * SAX based tests *
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000837 * *
838 ************************************************************************/
839
840/*
841 * empty SAX block
842 */
Daniel Veillard24505b02005-07-28 23:49:35 +0000843static xmlSAXHandler emptySAXHandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000844 NULL, /* internalSubset */
845 NULL, /* isStandalone */
846 NULL, /* hasInternalSubset */
847 NULL, /* hasExternalSubset */
848 NULL, /* resolveEntity */
849 NULL, /* getEntity */
850 NULL, /* entityDecl */
851 NULL, /* notationDecl */
852 NULL, /* attributeDecl */
853 NULL, /* elementDecl */
854 NULL, /* unparsedEntityDecl */
855 NULL, /* setDocumentLocator */
856 NULL, /* startDocument */
857 NULL, /* endDocument */
858 NULL, /* startElement */
859 NULL, /* endElement */
860 NULL, /* reference */
861 NULL, /* characters */
862 NULL, /* ignorableWhitespace */
863 NULL, /* processingInstruction */
864 NULL, /* comment */
865 NULL, /* xmlParserWarning */
866 NULL, /* xmlParserError */
867 NULL, /* xmlParserError */
868 NULL, /* getParameterEntity */
869 NULL, /* cdataBlock; */
870 NULL, /* externalSubset; */
Daniel Veillard971771e2005-07-09 17:32:57 +0000871 XML_SAX2_MAGIC,
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000872 NULL,
873 NULL, /* startElementNs */
874 NULL, /* endElementNs */
875 NULL /* xmlStructuredErrorFunc */
876};
877
Daniel Veillard24505b02005-07-28 23:49:35 +0000878static xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000879extern xmlSAXHandlerPtr debugSAXHandler;
880static int callbacks;
881
882/**
883 * isStandaloneDebug:
884 * @ctxt: An XML parser context
885 *
886 * Is this document tagged standalone ?
887 *
888 * Returns 1 if true
889 */
890static int
891isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
892{
893 callbacks++;
894 if (noout)
895 return(0);
896 fprintf(stdout, "SAX.isStandalone()\n");
897 return(0);
898}
899
900/**
901 * hasInternalSubsetDebug:
902 * @ctxt: An XML parser context
903 *
904 * Does this document has an internal subset
905 *
906 * Returns 1 if true
907 */
908static int
909hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
910{
911 callbacks++;
912 if (noout)
913 return(0);
914 fprintf(stdout, "SAX.hasInternalSubset()\n");
915 return(0);
916}
917
918/**
919 * hasExternalSubsetDebug:
920 * @ctxt: An XML parser context
921 *
922 * Does this document has an external subset
923 *
924 * Returns 1 if true
925 */
926static int
927hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
928{
929 callbacks++;
930 if (noout)
931 return(0);
932 fprintf(stdout, "SAX.hasExternalSubset()\n");
933 return(0);
934}
935
936/**
937 * internalSubsetDebug:
938 * @ctxt: An XML parser context
939 *
940 * Does this document has an internal subset
941 */
942static void
943internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
944 const xmlChar *ExternalID, const xmlChar *SystemID)
945{
946 callbacks++;
947 if (noout)
948 return;
949 fprintf(stdout, "SAX.internalSubset(%s,", name);
950 if (ExternalID == NULL)
951 fprintf(stdout, " ,");
952 else
953 fprintf(stdout, " %s,", ExternalID);
954 if (SystemID == NULL)
955 fprintf(stdout, " )\n");
956 else
957 fprintf(stdout, " %s)\n", SystemID);
958}
959
960/**
961 * externalSubsetDebug:
962 * @ctxt: An XML parser context
963 *
964 * Does this document has an external subset
965 */
966static void
967externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
968 const xmlChar *ExternalID, const xmlChar *SystemID)
969{
970 callbacks++;
971 if (noout)
972 return;
973 fprintf(stdout, "SAX.externalSubset(%s,", name);
974 if (ExternalID == NULL)
975 fprintf(stdout, " ,");
976 else
977 fprintf(stdout, " %s,", ExternalID);
978 if (SystemID == NULL)
979 fprintf(stdout, " )\n");
980 else
981 fprintf(stdout, " %s)\n", SystemID);
982}
983
984/**
985 * resolveEntityDebug:
986 * @ctxt: An XML parser context
987 * @publicId: The public ID of the entity
988 * @systemId: The system ID of the entity
989 *
990 * Special entity resolver, better left to the parser, it has
991 * more context than the application layer.
992 * The default behaviour is to NOT resolve the entities, in that case
993 * the ENTITY_REF nodes are built in the structure (and the parameter
994 * values).
995 *
996 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
997 */
998static xmlParserInputPtr
999resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
1000{
1001 callbacks++;
1002 if (noout)
1003 return(NULL);
1004 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1005
Daniel Veillardf1edb102009-08-10 14:43:18 +02001006
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001007 fprintf(stdout, "SAX.resolveEntity(");
1008 if (publicId != NULL)
1009 fprintf(stdout, "%s", (char *)publicId);
1010 else
1011 fprintf(stdout, " ");
1012 if (systemId != NULL)
1013 fprintf(stdout, ", %s)\n", (char *)systemId);
1014 else
1015 fprintf(stdout, ", )\n");
1016 return(NULL);
1017}
1018
1019/**
1020 * getEntityDebug:
1021 * @ctxt: An XML parser context
1022 * @name: The entity name
1023 *
1024 * Get an entity by name
1025 *
1026 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
1027 */
1028static xmlEntityPtr
1029getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1030{
1031 callbacks++;
1032 if (noout)
1033 return(NULL);
1034 fprintf(stdout, "SAX.getEntity(%s)\n", name);
1035 return(NULL);
1036}
1037
1038/**
1039 * getParameterEntityDebug:
1040 * @ctxt: An XML parser context
1041 * @name: The entity name
1042 *
1043 * Get a parameter entity by name
1044 *
1045 * Returns the xmlParserInputPtr
1046 */
1047static xmlEntityPtr
1048getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1049{
1050 callbacks++;
1051 if (noout)
1052 return(NULL);
1053 fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
1054 return(NULL);
1055}
1056
1057
1058/**
1059 * entityDeclDebug:
1060 * @ctxt: An XML parser context
Daniel Veillardf1edb102009-08-10 14:43:18 +02001061 * @name: the entity name
1062 * @type: the entity type
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001063 * @publicId: The public ID of the entity
1064 * @systemId: The system ID of the entity
1065 * @content: the entity value (without processing).
1066 *
1067 * An entity definition has been parsed
1068 */
1069static void
1070entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
1071 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
1072{
1073const xmlChar *nullstr = BAD_CAST "(null)";
1074 /* not all libraries handle printing null pointers nicely */
1075 if (publicId == NULL)
1076 publicId = nullstr;
1077 if (systemId == NULL)
1078 systemId = nullstr;
1079 if (content == NULL)
1080 content = (xmlChar *)nullstr;
1081 callbacks++;
1082 if (noout)
1083 return;
1084 fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
1085 name, type, publicId, systemId, content);
1086}
1087
1088/**
1089 * attributeDeclDebug:
1090 * @ctxt: An XML parser context
Daniel Veillardf1edb102009-08-10 14:43:18 +02001091 * @name: the attribute name
1092 * @type: the attribute type
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001093 *
1094 * An attribute definition has been parsed
1095 */
1096static void
1097attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar * elem,
1098 const xmlChar * name, int type, int def,
1099 const xmlChar * defaultValue, xmlEnumerationPtr tree)
1100{
1101 callbacks++;
1102 if (noout)
1103 return;
1104 if (defaultValue == NULL)
1105 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
1106 elem, name, type, def);
1107 else
1108 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
1109 elem, name, type, def, defaultValue);
1110 xmlFreeEnumeration(tree);
1111}
1112
1113/**
1114 * elementDeclDebug:
1115 * @ctxt: An XML parser context
Daniel Veillardf1edb102009-08-10 14:43:18 +02001116 * @name: the element name
1117 * @type: the element type
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001118 * @content: the element value (without processing).
1119 *
1120 * An element definition has been parsed
1121 */
1122static void
1123elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
1124 xmlElementContentPtr content ATTRIBUTE_UNUSED)
1125{
1126 callbacks++;
1127 if (noout)
1128 return;
1129 fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
1130 name, type);
1131}
1132
1133/**
1134 * notationDeclDebug:
1135 * @ctxt: An XML parser context
1136 * @name: The name of the notation
1137 * @publicId: The public ID of the entity
1138 * @systemId: The system ID of the entity
1139 *
1140 * What to do when a notation declaration has been parsed.
1141 */
1142static void
1143notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
1144 const xmlChar *publicId, const xmlChar *systemId)
1145{
1146 callbacks++;
1147 if (noout)
1148 return;
1149 fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
1150 (char *) name, (char *) publicId, (char *) systemId);
1151}
1152
1153/**
1154 * unparsedEntityDeclDebug:
1155 * @ctxt: An XML parser context
1156 * @name: The name of the entity
1157 * @publicId: The public ID of the entity
1158 * @systemId: The system ID of the entity
1159 * @notationName: the name of the notation
1160 *
1161 * What to do when an unparsed entity declaration is parsed
1162 */
1163static void
1164unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
1165 const xmlChar *publicId, const xmlChar *systemId,
1166 const xmlChar *notationName)
1167{
1168const xmlChar *nullstr = BAD_CAST "(null)";
1169
1170 if (publicId == NULL)
1171 publicId = nullstr;
1172 if (systemId == NULL)
1173 systemId = nullstr;
1174 if (notationName == NULL)
1175 notationName = nullstr;
1176 callbacks++;
1177 if (noout)
1178 return;
1179 fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
1180 (char *) name, (char *) publicId, (char *) systemId,
1181 (char *) notationName);
1182}
1183
1184/**
1185 * setDocumentLocatorDebug:
1186 * @ctxt: An XML parser context
1187 * @loc: A SAX Locator
1188 *
1189 * Receive the document locator at startup, actually xmlDefaultSAXLocator
1190 * Everything is available on the context, so this is useless in our case.
1191 */
1192static void
1193setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
1194{
1195 callbacks++;
1196 if (noout)
1197 return;
1198 fprintf(stdout, "SAX.setDocumentLocator()\n");
1199}
1200
1201/**
1202 * startDocumentDebug:
1203 * @ctxt: An XML parser context
1204 *
1205 * called when the document start being processed.
1206 */
1207static void
1208startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
1209{
1210 callbacks++;
1211 if (noout)
1212 return;
1213 fprintf(stdout, "SAX.startDocument()\n");
1214}
1215
1216/**
1217 * endDocumentDebug:
1218 * @ctxt: An XML parser context
1219 *
1220 * called when the document end has been detected.
1221 */
1222static void
1223endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
1224{
1225 callbacks++;
1226 if (noout)
1227 return;
1228 fprintf(stdout, "SAX.endDocument()\n");
1229}
1230
1231/**
1232 * startElementDebug:
1233 * @ctxt: An XML parser context
1234 * @name: The element name
1235 *
1236 * called when an opening tag has been processed.
1237 */
1238static void
1239startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
1240{
1241 int i;
1242
1243 callbacks++;
1244 if (noout)
1245 return;
1246 fprintf(stdout, "SAX.startElement(%s", (char *) name);
1247 if (atts != NULL) {
1248 for (i = 0;(atts[i] != NULL);i++) {
1249 fprintf(stdout, ", %s='", atts[i++]);
1250 if (atts[i] != NULL)
1251 fprintf(stdout, "%s'", atts[i]);
1252 }
1253 }
1254 fprintf(stdout, ")\n");
1255}
1256
1257/**
1258 * endElementDebug:
1259 * @ctxt: An XML parser context
1260 * @name: The element name
1261 *
1262 * called when the end of an element has been detected.
1263 */
1264static void
1265endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1266{
1267 callbacks++;
1268 if (noout)
1269 return;
1270 fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
1271}
1272
1273/**
1274 * charactersDebug:
1275 * @ctxt: An XML parser context
1276 * @ch: a xmlChar string
1277 * @len: the number of xmlChar
1278 *
1279 * receiving some chars from the parser.
1280 * Question: how much at a time ???
1281 */
1282static void
1283charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
1284{
1285 char out[40];
1286 int i;
1287
1288 callbacks++;
1289 if (noout)
1290 return;
1291 for (i = 0;(i<len) && (i < 30);i++)
1292 out[i] = ch[i];
1293 out[i] = 0;
1294
1295 fprintf(stdout, "SAX.characters(%s, %d)\n", out, len);
1296}
1297
1298/**
1299 * referenceDebug:
1300 * @ctxt: An XML parser context
1301 * @name: The entity name
1302 *
Daniel Veillardf1edb102009-08-10 14:43:18 +02001303 * called when an entity reference is detected.
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001304 */
1305static void
1306referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1307{
1308 callbacks++;
1309 if (noout)
1310 return;
1311 fprintf(stdout, "SAX.reference(%s)\n", name);
1312}
1313
1314/**
1315 * ignorableWhitespaceDebug:
1316 * @ctxt: An XML parser context
1317 * @ch: a xmlChar string
1318 * @start: the first char in the string
1319 * @len: the number of xmlChar
1320 *
1321 * receiving some ignorable whitespaces from the parser.
1322 * Question: how much at a time ???
1323 */
1324static void
1325ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
1326{
1327 char out[40];
1328 int i;
1329
1330 callbacks++;
1331 if (noout)
1332 return;
1333 for (i = 0;(i<len) && (i < 30);i++)
1334 out[i] = ch[i];
1335 out[i] = 0;
1336 fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", out, len);
1337}
1338
1339/**
1340 * processingInstructionDebug:
1341 * @ctxt: An XML parser context
1342 * @target: the target name
1343 * @data: the PI data's
1344 * @len: the number of xmlChar
1345 *
1346 * A processing instruction has been parsed.
1347 */
1348static void
1349processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
1350 const xmlChar *data)
1351{
1352 callbacks++;
1353 if (noout)
1354 return;
1355 if (data != NULL)
1356 fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
1357 (char *) target, (char *) data);
1358 else
1359 fprintf(stdout, "SAX.processingInstruction(%s, NULL)\n",
1360 (char *) target);
1361}
1362
1363/**
1364 * cdataBlockDebug:
1365 * @ctx: the user data (XML parser context)
1366 * @value: The pcdata content
1367 * @len: the block length
1368 *
1369 * called when a pcdata block has been parsed
1370 */
1371static void
1372cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
1373{
1374 callbacks++;
1375 if (noout)
1376 return;
1377 fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
1378 (char *) value, len);
1379}
1380
1381/**
1382 * commentDebug:
1383 * @ctxt: An XML parser context
1384 * @value: the comment content
1385 *
1386 * A comment has been parsed.
1387 */
1388static void
1389commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
1390{
1391 callbacks++;
1392 if (noout)
1393 return;
1394 fprintf(stdout, "SAX.comment(%s)\n", value);
1395}
1396
1397/**
1398 * warningDebug:
1399 * @ctxt: An XML parser context
1400 * @msg: the message to display/transmit
1401 * @...: extra parameters for the message display
1402 *
1403 * Display and format a warning messages, gives file, line, position and
1404 * extra parameters.
1405 */
David Kilzer4472c3a2016-05-13 15:13:17 +08001406static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001407warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1408{
1409 va_list args;
1410
1411 callbacks++;
1412 if (noout)
1413 return;
1414 va_start(args, msg);
1415 fprintf(stdout, "SAX.warning: ");
1416 vfprintf(stdout, msg, args);
1417 va_end(args);
1418}
1419
1420/**
1421 * errorDebug:
1422 * @ctxt: An XML parser context
1423 * @msg: the message to display/transmit
1424 * @...: extra parameters for the message display
1425 *
1426 * Display and format a error messages, gives file, line, position and
1427 * extra parameters.
1428 */
David Kilzer4472c3a2016-05-13 15:13:17 +08001429static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001430errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1431{
1432 va_list args;
1433
1434 callbacks++;
1435 if (noout)
1436 return;
1437 va_start(args, msg);
1438 fprintf(stdout, "SAX.error: ");
1439 vfprintf(stdout, msg, args);
1440 va_end(args);
1441}
1442
1443/**
1444 * fatalErrorDebug:
1445 * @ctxt: An XML parser context
1446 * @msg: the message to display/transmit
1447 * @...: extra parameters for the message display
1448 *
1449 * Display and format a fatalError messages, gives file, line, position and
1450 * extra parameters.
1451 */
David Kilzer4472c3a2016-05-13 15:13:17 +08001452static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001453fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1454{
1455 va_list args;
1456
1457 callbacks++;
1458 if (noout)
1459 return;
1460 va_start(args, msg);
1461 fprintf(stdout, "SAX.fatalError: ");
1462 vfprintf(stdout, msg, args);
1463 va_end(args);
1464}
1465
Daniel Veillard24505b02005-07-28 23:49:35 +00001466static xmlSAXHandler debugSAXHandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001467 internalSubsetDebug,
1468 isStandaloneDebug,
1469 hasInternalSubsetDebug,
1470 hasExternalSubsetDebug,
1471 resolveEntityDebug,
1472 getEntityDebug,
1473 entityDeclDebug,
1474 notationDeclDebug,
1475 attributeDeclDebug,
1476 elementDeclDebug,
1477 unparsedEntityDeclDebug,
1478 setDocumentLocatorDebug,
1479 startDocumentDebug,
1480 endDocumentDebug,
1481 startElementDebug,
1482 endElementDebug,
1483 referenceDebug,
1484 charactersDebug,
1485 ignorableWhitespaceDebug,
1486 processingInstructionDebug,
1487 commentDebug,
1488 warningDebug,
1489 errorDebug,
1490 fatalErrorDebug,
1491 getParameterEntityDebug,
1492 cdataBlockDebug,
1493 externalSubsetDebug,
1494 1,
1495 NULL,
1496 NULL,
1497 NULL,
1498 NULL
1499};
1500
1501xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
1502
1503/*
1504 * SAX2 specific callbacks
1505 */
1506/**
1507 * startElementNsDebug:
1508 * @ctxt: An XML parser context
1509 * @name: The element name
1510 *
1511 * called when an opening tag has been processed.
1512 */
1513static void
1514startElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
1515 const xmlChar *localname,
1516 const xmlChar *prefix,
1517 const xmlChar *URI,
1518 int nb_namespaces,
1519 const xmlChar **namespaces,
1520 int nb_attributes,
1521 int nb_defaulted,
1522 const xmlChar **attributes)
1523{
1524 int i;
1525
1526 callbacks++;
1527 if (noout)
1528 return;
1529 fprintf(stdout, "SAX.startElementNs(%s", (char *) localname);
1530 if (prefix == NULL)
1531 fprintf(stdout, ", NULL");
1532 else
1533 fprintf(stdout, ", %s", (char *) prefix);
1534 if (URI == NULL)
1535 fprintf(stdout, ", NULL");
1536 else
1537 fprintf(stdout, ", '%s'", (char *) URI);
1538 fprintf(stdout, ", %d", nb_namespaces);
Daniel Veillardf1edb102009-08-10 14:43:18 +02001539
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001540 if (namespaces != NULL) {
1541 for (i = 0;i < nb_namespaces * 2;i++) {
1542 fprintf(stdout, ", xmlns");
1543 if (namespaces[i] != NULL)
1544 fprintf(stdout, ":%s", namespaces[i]);
1545 i++;
1546 fprintf(stdout, "='%s'", namespaces[i]);
1547 }
1548 }
1549 fprintf(stdout, ", %d, %d", nb_attributes, nb_defaulted);
1550 if (attributes != NULL) {
1551 for (i = 0;i < nb_attributes * 5;i += 5) {
1552 if (attributes[i + 1] != NULL)
1553 fprintf(stdout, ", %s:%s='", attributes[i + 1], attributes[i]);
1554 else
1555 fprintf(stdout, ", %s='", attributes[i]);
1556 fprintf(stdout, "%.4s...', %d", attributes[i + 3],
1557 (int)(attributes[i + 4] - attributes[i + 3]));
1558 }
1559 }
1560 fprintf(stdout, ")\n");
1561}
1562
1563/**
1564 * endElementDebug:
1565 * @ctxt: An XML parser context
1566 * @name: The element name
1567 *
1568 * called when the end of an element has been detected.
1569 */
1570static void
1571endElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
1572 const xmlChar *localname,
1573 const xmlChar *prefix,
1574 const xmlChar *URI)
1575{
1576 callbacks++;
1577 if (noout)
1578 return;
1579 fprintf(stdout, "SAX.endElementNs(%s", (char *) localname);
1580 if (prefix == NULL)
1581 fprintf(stdout, ", NULL");
1582 else
1583 fprintf(stdout, ", %s", (char *) prefix);
1584 if (URI == NULL)
1585 fprintf(stdout, ", NULL)\n");
1586 else
1587 fprintf(stdout, ", '%s')\n", (char *) URI);
1588}
1589
Daniel Veillard24505b02005-07-28 23:49:35 +00001590static xmlSAXHandler debugSAX2HandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001591 internalSubsetDebug,
1592 isStandaloneDebug,
1593 hasInternalSubsetDebug,
1594 hasExternalSubsetDebug,
1595 resolveEntityDebug,
1596 getEntityDebug,
1597 entityDeclDebug,
1598 notationDeclDebug,
1599 attributeDeclDebug,
1600 elementDeclDebug,
1601 unparsedEntityDeclDebug,
1602 setDocumentLocatorDebug,
1603 startDocumentDebug,
1604 endDocumentDebug,
1605 NULL,
1606 NULL,
1607 referenceDebug,
1608 charactersDebug,
1609 ignorableWhitespaceDebug,
1610 processingInstructionDebug,
1611 commentDebug,
1612 warningDebug,
1613 errorDebug,
1614 fatalErrorDebug,
1615 getParameterEntityDebug,
1616 cdataBlockDebug,
1617 externalSubsetDebug,
1618 XML_SAX2_MAGIC,
1619 NULL,
1620 startElementNsDebug,
1621 endElementNsDebug,
1622 NULL
1623};
1624
Daniel Veillard24505b02005-07-28 23:49:35 +00001625static xmlSAXHandlerPtr debugSAX2Handler = &debugSAX2HandlerStruct;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001626
1627static void
1628testSAX(const char *filename) {
1629 xmlSAXHandlerPtr handler;
1630 const char *user_data = "user_data"; /* mostly for debugging */
1631 xmlParserInputBufferPtr buf = NULL;
1632 xmlParserInputPtr inputStream;
1633 xmlParserCtxtPtr ctxt = NULL;
1634 xmlSAXHandlerPtr old_sax = NULL;
1635
1636 callbacks = 0;
1637
1638 if (noout) {
1639 handler = emptySAXHandler;
Daniel Veillard78dfc9f2005-07-10 22:30:30 +00001640#ifdef LIBXML_SAX1_ENABLED
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001641 } else if (sax1) {
1642 handler = debugSAXHandler;
Daniel Veillard78dfc9f2005-07-10 22:30:30 +00001643#endif
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001644 } else {
1645 handler = debugSAX2Handler;
1646 }
1647
1648 /*
1649 * it's not the simplest code but the most generic in term of I/O
1650 */
1651 buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
1652 if (buf == NULL) {
1653 goto error;
1654 }
1655
1656#ifdef LIBXML_SCHEMAS_ENABLED
1657 if (wxschemas != NULL) {
1658 int ret;
1659 xmlSchemaValidCtxtPtr vctxt;
1660
1661 vctxt = xmlSchemaNewValidCtxt(wxschemas);
Haibo Huangcfd91dc2020-07-30 23:01:33 -07001662 xmlSchemaSetValidErrors(vctxt, xmlGenericError, xmlGenericError, NULL);
Daniel Veillard97fa5b32012-08-14 11:01:07 +08001663 xmlSchemaValidateSetFilename(vctxt, filename);
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001664
Daniel Veillard971771e2005-07-09 17:32:57 +00001665 ret = xmlSchemaValidateStream(vctxt, buf, 0, handler,
1666 (void *)user_data);
1667 if (repeat == 0) {
1668 if (ret == 0) {
Haibo Huang735158e2021-02-23 17:48:08 -08001669 if (!quiet) {
1670 fprintf(stderr, "%s validates\n", filename);
1671 }
Daniel Veillard971771e2005-07-09 17:32:57 +00001672 } else if (ret > 0) {
1673 fprintf(stderr, "%s fails to validate\n", filename);
1674 progresult = XMLLINT_ERR_VALID;
1675 } else {
1676 fprintf(stderr, "%s validation generated an internal error\n",
1677 filename);
1678 progresult = XMLLINT_ERR_VALID;
1679 }
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001680 }
1681 xmlSchemaFreeValidCtxt(vctxt);
1682 } else
1683#endif
1684 {
1685 /*
1686 * Create the parser context amd hook the input
1687 */
1688 ctxt = xmlNewParserCtxt();
1689 if (ctxt == NULL) {
1690 xmlFreeParserInputBuffer(buf);
1691 goto error;
1692 }
1693 old_sax = ctxt->sax;
1694 ctxt->sax = handler;
1695 ctxt->userData = (void *) user_data;
1696 inputStream = xmlNewIOInputStream(ctxt, buf, XML_CHAR_ENCODING_NONE);
1697 if (inputStream == NULL) {
1698 xmlFreeParserInputBuffer(buf);
1699 goto error;
1700 }
1701 inputPush(ctxt, inputStream);
Daniel Veillardf1edb102009-08-10 14:43:18 +02001702
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001703 /* do the parsing */
1704 xmlParseDocument(ctxt);
1705
1706 if (ctxt->myDoc != NULL) {
1707 fprintf(stderr, "SAX generated a doc !\n");
1708 xmlFreeDoc(ctxt->myDoc);
1709 ctxt->myDoc = NULL;
1710 }
1711 }
1712
1713error:
1714 if (ctxt != NULL) {
1715 ctxt->sax = old_sax;
1716 xmlFreeParserCtxt(ctxt);
1717 }
1718}
1719
Daniel Veillard5e873c42000-04-12 13:27:38 +00001720/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +02001721 * *
1722 * Stream Test processing *
1723 * *
Daniel Veillard7704fb12003-01-03 16:19:51 +00001724 ************************************************************************/
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001725#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00001726static void processNode(xmlTextReaderPtr reader) {
Daniel Veillard198c1bf2003-10-20 17:07:41 +00001727 const xmlChar *name, *value;
Daniel Veillard16ef8002005-01-31 00:27:50 +00001728 int type, empty;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001729
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001730 type = xmlTextReaderNodeType(reader);
Daniel Veillard16ef8002005-01-31 00:27:50 +00001731 empty = xmlTextReaderIsEmptyElement(reader);
Daniel Veillard99737f52003-03-22 14:55:50 +00001732
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001733 if (debug) {
1734 name = xmlTextReaderConstName(reader);
1735 if (name == NULL)
1736 name = BAD_CAST "--";
Daniel Veillard7704fb12003-01-03 16:19:51 +00001737
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001738 value = xmlTextReaderConstValue(reader);
1739
Daniel Veillardf1edb102009-08-10 14:43:18 +02001740
1741 printf("%d %d %s %d %d",
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001742 xmlTextReaderDepth(reader),
1743 type,
1744 name,
Daniel Veillard16ef8002005-01-31 00:27:50 +00001745 empty,
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001746 xmlTextReaderHasValue(reader));
1747 if (value == NULL)
1748 printf("\n");
1749 else {
1750 printf(" %s\n", value);
1751 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001752 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001753#ifdef LIBXML_PATTERN_ENABLED
1754 if (patternc) {
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001755 xmlChar *path = NULL;
1756 int match = -1;
Daniel Veillardf1edb102009-08-10 14:43:18 +02001757
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001758 if (type == XML_READER_TYPE_ELEMENT) {
1759 /* do the check only on element start */
1760 match = xmlPatternMatch(patternc, xmlTextReaderCurrentNode(reader));
1761
1762 if (match) {
Daniel Veillardf1edb102009-08-10 14:43:18 +02001763#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001764 path = xmlGetNodePath(xmlTextReaderCurrentNode(reader));
1765 printf("Node %s matches pattern %s\n", path, pattern);
Daniel Veillardf1edb102009-08-10 14:43:18 +02001766#else
1767 printf("Node %s matches pattern %s\n",
1768 xmlTextReaderConstName(reader), pattern);
1769#endif
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001770 }
1771 }
1772 if (patstream != NULL) {
1773 int ret;
1774
1775 if (type == XML_READER_TYPE_ELEMENT) {
1776 ret = xmlStreamPush(patstream,
1777 xmlTextReaderConstLocalName(reader),
1778 xmlTextReaderConstNamespaceUri(reader));
1779 if (ret < 0) {
1780 fprintf(stderr, "xmlStreamPush() failure\n");
1781 xmlFreeStreamCtxt(patstream);
1782 patstream = NULL;
1783 } else if (ret != match) {
Daniel Veillardf1edb102009-08-10 14:43:18 +02001784#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001785 if (path == NULL) {
1786 path = xmlGetNodePath(
1787 xmlTextReaderCurrentNode(reader));
1788 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02001789#endif
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001790 fprintf(stderr,
1791 "xmlPatternMatch and xmlStreamPush disagree\n");
Daniel Veillardf1edb102009-08-10 14:43:18 +02001792 if (path != NULL)
1793 fprintf(stderr, " pattern %s node %s\n",
1794 pattern, path);
1795 else
1796 fprintf(stderr, " pattern %s node %s\n",
1797 pattern, xmlTextReaderConstName(reader));
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001798 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001799
Daniel Veillardf1edb102009-08-10 14:43:18 +02001800 }
Daniel Veillard16ef8002005-01-31 00:27:50 +00001801 if ((type == XML_READER_TYPE_END_ELEMENT) ||
1802 ((type == XML_READER_TYPE_ELEMENT) && (empty))) {
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001803 ret = xmlStreamPop(patstream);
1804 if (ret < 0) {
1805 fprintf(stderr, "xmlStreamPop() failure\n");
1806 xmlFreeStreamCtxt(patstream);
1807 patstream = NULL;
1808 }
1809 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001810 }
Daniel Veillardf9d16912005-01-30 22:36:30 +00001811 if (path != NULL)
1812 xmlFree(path);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001813 }
1814#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001815}
1816
1817static void streamFile(char *filename) {
1818 xmlTextReaderPtr reader;
1819 int ret;
Daniel Richard G5706b6d2012-08-06 11:32:54 +08001820#ifdef HAVE_MMAP
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001821 int fd = -1;
1822 struct stat info;
1823 const char *base = NULL;
1824 xmlParserInputBufferPtr input = NULL;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001825
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001826 if (memory) {
Daniel Veillardf1edb102009-08-10 14:43:18 +02001827 if (stat(filename, &info) < 0)
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001828 return;
1829 if ((fd = open(filename, O_RDONLY)) < 0)
1830 return;
1831 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillardb98c6a02013-07-12 12:08:40 +08001832 if (base == (void *) MAP_FAILED) {
1833 close(fd);
1834 fprintf(stderr, "mmap failure for file %s\n", filename);
1835 progresult = XMLLINT_ERR_RDFILE;
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001836 return;
Daniel Veillardb98c6a02013-07-12 12:08:40 +08001837 }
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001838
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001839 reader = xmlReaderForMemory(base, info.st_size, filename,
1840 NULL, options);
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001841 } else
1842#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001843 reader = xmlReaderForFile(filename, NULL, options);
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001844#ifdef LIBXML_PATTERN_ENABLED
Daniel Veillardd4301ab2005-02-03 22:24:10 +00001845 if (pattern != NULL) {
1846 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
1847 if (patternc == NULL) {
1848 xmlGenericError(xmlGenericErrorContext,
1849 "Pattern %s failed to compile\n", pattern);
1850 progresult = XMLLINT_ERR_SCHEMAPAT;
1851 pattern = NULL;
1852 }
1853 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001854 if (patternc != NULL) {
1855 patstream = xmlPatternGetStreamCtxt(patternc);
1856 if (patstream != NULL) {
1857 ret = xmlStreamPush(patstream, NULL, NULL);
1858 if (ret < 0) {
1859 fprintf(stderr, "xmlStreamPush() failure\n");
1860 xmlFreeStreamCtxt(patstream);
1861 patstream = NULL;
1862 }
1863 }
1864 }
1865#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001866
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001867
Daniel Veillard7704fb12003-01-03 16:19:51 +00001868 if (reader != NULL) {
Daniel Veillard4432df22003-09-28 18:58:27 +00001869#ifdef LIBXML_VALID_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00001870 if (valid)
1871 xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
Daniel Veillardce192eb2003-04-16 15:58:05 +00001872 else
Daniel Veillard4432df22003-09-28 18:58:27 +00001873#endif /* LIBXML_VALID_ENABLED */
Daniel Veillarde4d16d72012-12-21 10:58:14 +08001874 if (loaddtd)
1875 xmlTextReaderSetParserProp(reader, XML_PARSER_LOADDTD, 1);
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001876#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +00001877 if (relaxng != NULL) {
Daniel Veillard81514ba2003-09-16 23:17:26 +00001878 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001879 startTimer();
1880 }
1881 ret = xmlTextReaderRelaxNGValidate(reader, relaxng);
1882 if (ret < 0) {
1883 xmlGenericError(xmlGenericErrorContext,
1884 "Relax-NG schema %s failed to compile\n", relaxng);
William M. Brack8304d872004-06-08 13:29:32 +00001885 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillardce192eb2003-04-16 15:58:05 +00001886 relaxng = NULL;
1887 }
Daniel Veillard81514ba2003-09-16 23:17:26 +00001888 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001889 endTimer("Compiling the schemas");
1890 }
1891 }
Daniel Veillardf10ae122005-07-10 19:03:16 +00001892 if (schema != NULL) {
1893 if ((timing) && (!repeat)) {
1894 startTimer();
1895 }
1896 ret = xmlTextReaderSchemaValidate(reader, schema);
1897 if (ret < 0) {
1898 xmlGenericError(xmlGenericErrorContext,
1899 "XSD schema %s failed to compile\n", schema);
1900 progresult = XMLLINT_ERR_SCHEMACOMP;
1901 schema = NULL;
1902 }
1903 if ((timing) && (!repeat)) {
1904 endTimer("Compiling the schemas");
1905 }
1906 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001907#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001908
1909 /*
1910 * Process all nodes in sequence
1911 */
Daniel Veillard81514ba2003-09-16 23:17:26 +00001912 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001913 startTimer();
1914 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001915 ret = xmlTextReaderRead(reader);
1916 while (ret == 1) {
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001917 if ((debug)
1918#ifdef LIBXML_PATTERN_ENABLED
1919 || (patternc)
1920#endif
1921 )
Daniel Veillard7704fb12003-01-03 16:19:51 +00001922 processNode(reader);
1923 ret = xmlTextReaderRead(reader);
1924 }
Daniel Veillard81514ba2003-09-16 23:17:26 +00001925 if ((timing) && (!repeat)) {
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001926#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf54cd532004-02-25 11:52:31 +00001927 if (relaxng != NULL)
Daniel Veillard49138f12004-02-19 12:58:36 +00001928 endTimer("Parsing and validating");
1929 else
Daniel Veillardf54cd532004-02-25 11:52:31 +00001930#endif
Daniel Veillard4432df22003-09-28 18:58:27 +00001931#ifdef LIBXML_VALID_ENABLED
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001932 if (valid)
Daniel Veillardce192eb2003-04-16 15:58:05 +00001933 endTimer("Parsing and validating");
1934 else
Daniel Veillard4432df22003-09-28 18:58:27 +00001935#endif
Daniel Veillardf54cd532004-02-25 11:52:31 +00001936 endTimer("Parsing");
Daniel Veillardce192eb2003-04-16 15:58:05 +00001937 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001938
Daniel Veillard4432df22003-09-28 18:58:27 +00001939#ifdef LIBXML_VALID_ENABLED
Daniel Veillardf6bad792003-04-11 19:38:54 +00001940 if (valid) {
1941 if (xmlTextReaderIsValid(reader) != 1) {
1942 xmlGenericError(xmlGenericErrorContext,
1943 "Document %s does not validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001944 progresult = XMLLINT_ERR_VALID;
Daniel Veillardf6bad792003-04-11 19:38:54 +00001945 }
1946 }
Daniel Veillard4432df22003-09-28 18:58:27 +00001947#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001948#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf10ae122005-07-10 19:03:16 +00001949 if ((relaxng != NULL) || (schema != NULL)) {
Daniel Veillardf4e55762003-04-15 23:32:22 +00001950 if (xmlTextReaderIsValid(reader) != 1) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001951 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001952 progresult = XMLLINT_ERR_VALID;
Daniel Veillardf4e55762003-04-15 23:32:22 +00001953 } else {
Haibo Huang735158e2021-02-23 17:48:08 -08001954 if (!quiet) {
1955 fprintf(stderr, "%s validates\n", filename);
1956 }
Daniel Veillardf4e55762003-04-15 23:32:22 +00001957 }
1958 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001959#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001960 /*
1961 * Done, cleanup and status
1962 */
1963 xmlFreeTextReader(reader);
1964 if (ret != 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001965 fprintf(stderr, "%s : failed to parse\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001966 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001967 }
1968 } else {
1969 fprintf(stderr, "Unable to open %s\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001970 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001971 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001972#ifdef LIBXML_PATTERN_ENABLED
1973 if (patstream != NULL) {
1974 xmlFreeStreamCtxt(patstream);
1975 patstream = NULL;
1976 }
1977#endif
Daniel Richard G5706b6d2012-08-06 11:32:54 +08001978#ifdef HAVE_MMAP
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001979 if (memory) {
1980 xmlFreeParserInputBuffer(input);
1981 munmap((char *) base, info.st_size);
1982 close(fd);
1983 }
1984#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001985}
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001986
1987static void walkDoc(xmlDocPtr doc) {
1988 xmlTextReaderPtr reader;
1989 int ret;
1990
Daniel Veillardd4301ab2005-02-03 22:24:10 +00001991#ifdef LIBXML_PATTERN_ENABLED
1992 xmlNodePtr root;
1993 const xmlChar *namespaces[22];
1994 int i;
1995 xmlNsPtr ns;
1996
1997 root = xmlDocGetRootElement(doc);
Hugh Davenportb8e0fa32016-05-04 10:55:49 +08001998 if (root == NULL ) {
1999 xmlGenericError(xmlGenericErrorContext,
2000 "Document does not have a root element");
2001 progresult = XMLLINT_ERR_UNCLASS;
2002 return;
2003 }
Daniel Veillardd4301ab2005-02-03 22:24:10 +00002004 for (ns = root->nsDef, i = 0;ns != NULL && i < 20;ns=ns->next) {
2005 namespaces[i++] = ns->href;
2006 namespaces[i++] = ns->prefix;
2007 }
2008 namespaces[i++] = NULL;
Daniel Veillard13cee4e2009-09-05 14:52:55 +02002009 namespaces[i] = NULL;
Daniel Veillardd4301ab2005-02-03 22:24:10 +00002010
2011 if (pattern != NULL) {
2012 patternc = xmlPatterncompile((const xmlChar *) pattern, doc->dict,
2013 0, &namespaces[0]);
2014 if (patternc == NULL) {
2015 xmlGenericError(xmlGenericErrorContext,
2016 "Pattern %s failed to compile\n", pattern);
2017 progresult = XMLLINT_ERR_SCHEMAPAT;
2018 pattern = NULL;
2019 }
2020 }
Daniel Veillard2b2e02d2005-02-05 23:20:22 +00002021 if (patternc != NULL) {
2022 patstream = xmlPatternGetStreamCtxt(patternc);
2023 if (patstream != NULL) {
2024 ret = xmlStreamPush(patstream, NULL, NULL);
2025 if (ret < 0) {
2026 fprintf(stderr, "xmlStreamPush() failure\n");
2027 xmlFreeStreamCtxt(patstream);
2028 patstream = NULL;
2029 }
2030 }
2031 }
Daniel Veillardd4301ab2005-02-03 22:24:10 +00002032#endif /* LIBXML_PATTERN_ENABLED */
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002033 reader = xmlReaderWalker(doc);
2034 if (reader != NULL) {
2035 if ((timing) && (!repeat)) {
2036 startTimer();
2037 }
2038 ret = xmlTextReaderRead(reader);
2039 while (ret == 1) {
Daniel Veillardb3de70c2003-12-02 22:32:15 +00002040 if ((debug)
2041#ifdef LIBXML_PATTERN_ENABLED
2042 || (patternc)
2043#endif
2044 )
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002045 processNode(reader);
2046 ret = xmlTextReaderRead(reader);
2047 }
2048 if ((timing) && (!repeat)) {
2049 endTimer("walking through the doc");
2050 }
2051 xmlFreeTextReader(reader);
2052 if (ret != 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002053 fprintf(stderr, "failed to walk through the doc\n");
William M. Brack8304d872004-06-08 13:29:32 +00002054 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002055 }
2056 } else {
2057 fprintf(stderr, "Failed to crate a reader from the document\n");
William M. Brack8304d872004-06-08 13:29:32 +00002058 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002059 }
Daniel Veillard2b2e02d2005-02-05 23:20:22 +00002060#ifdef LIBXML_PATTERN_ENABLED
2061 if (patstream != NULL) {
2062 xmlFreeStreamCtxt(patstream);
2063 patstream = NULL;
2064 }
2065#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002066}
Daniel Veillard81273902003-09-30 00:43:48 +00002067#endif /* LIBXML_READER_ENABLED */
Daniel Veillard7704fb12003-01-03 16:19:51 +00002068
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002069#ifdef LIBXML_XPATH_ENABLED
2070/************************************************************************
2071 * *
2072 * XPath Query *
2073 * *
2074 ************************************************************************/
2075
2076static void doXPathDump(xmlXPathObjectPtr cur) {
2077 switch(cur->type) {
2078 case XPATH_NODESET: {
2079 int i;
2080 xmlNodePtr node;
2081#ifdef LIBXML_OUTPUT_ENABLED
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002082 xmlOutputBufferPtr buf;
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002083
Daniel Veillardbdc64d62012-03-27 14:41:37 +08002084 if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr <= 0)) {
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002085 fprintf(stderr, "XPath set is empty\n");
2086 progresult = XMLLINT_ERR_XPATH;
2087 break;
2088 }
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002089 buf = xmlOutputBufferCreateFile(stdout, NULL);
2090 if (buf == NULL) {
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002091 fprintf(stderr, "Out of memory for XPath\n");
2092 progresult = XMLLINT_ERR_MEM;
2093 return;
2094 }
2095 for (i = 0;i < cur->nodesetval->nodeNr;i++) {
2096 node = cur->nodesetval->nodeTab[i];
Haibo Huangcfd91dc2020-07-30 23:01:33 -07002097 xmlNodeDumpOutput(buf, NULL, node, 0, 0, NULL);
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002098 xmlOutputBufferWrite(buf, 1, "\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002099 }
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002100 xmlOutputBufferClose(buf);
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002101#else
2102 printf("xpath returned %d nodes\n", cur->nodesetval->nodeNr);
2103#endif
2104 break;
2105 }
2106 case XPATH_BOOLEAN:
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002107 if (cur->boolval) printf("true\n");
2108 else printf("false\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002109 break;
2110 case XPATH_NUMBER:
2111 switch (xmlXPathIsInf(cur->floatval)) {
2112 case 1:
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002113 printf("Infinity\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002114 break;
2115 case -1:
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002116 printf("-Infinity\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002117 break;
2118 default:
2119 if (xmlXPathIsNaN(cur->floatval)) {
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002120 printf("NaN\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002121 } else {
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002122 printf("%0g\n", cur->floatval);
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002123 }
2124 }
2125 break;
2126 case XPATH_STRING:
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002127 printf("%s\n", (const char *) cur->stringval);
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002128 break;
2129 case XPATH_UNDEFINED:
2130 fprintf(stderr, "XPath Object is uninitialized\n");
2131 progresult = XMLLINT_ERR_XPATH;
2132 break;
2133 default:
2134 fprintf(stderr, "XPath object of unexpected type\n");
2135 progresult = XMLLINT_ERR_XPATH;
2136 break;
2137 }
2138}
2139
2140static void doXPathQuery(xmlDocPtr doc, const char *query) {
2141 xmlXPathContextPtr ctxt;
2142 xmlXPathObjectPtr res;
2143
2144 ctxt = xmlXPathNewContext(doc);
2145 if (ctxt == NULL) {
2146 fprintf(stderr, "Out of memory for XPath\n");
2147 progresult = XMLLINT_ERR_MEM;
2148 return;
2149 }
Daniel Veillard2e1eaca2012-05-25 16:44:20 +08002150 ctxt->node = (xmlNodePtr) doc;
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002151 res = xmlXPathEval(BAD_CAST query, ctxt);
2152 xmlXPathFreeContext(ctxt);
2153
2154 if (res == NULL) {
2155 fprintf(stderr, "XPath evaluation failure\n");
2156 progresult = XMLLINT_ERR_XPATH;
2157 return;
2158 }
2159 doXPathDump(res);
2160 xmlXPathFreeObject(res);
2161}
2162#endif /* LIBXML_XPATH_ENABLED */
2163
Daniel Veillard7704fb12003-01-03 16:19:51 +00002164/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +02002165 * *
2166 * Tree Test processing *
2167 * *
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002168 ************************************************************************/
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002169static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
Daniel Veillard652327a2003-09-29 18:02:38 +00002170 xmlDocPtr doc = NULL;
2171#ifdef LIBXML_TREE_ENABLED
2172 xmlDocPtr tmp;
2173#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002174
Daniel Veillard48b2f892001-02-25 16:11:03 +00002175 if ((timing) && (!repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00002176 startTimer();
Daniel Veillardf1edb102009-08-10 14:43:18 +02002177
Daniel Veillard48b2f892001-02-25 16:11:03 +00002178
Daniel Veillard652327a2003-09-29 18:02:38 +00002179#ifdef LIBXML_TREE_ENABLED
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002180 if (filename == NULL) {
2181 if (generate) {
2182 xmlNodePtr n;
2183
2184 doc = xmlNewDoc(BAD_CAST "1.0");
Daniel Veillard95ddcd32004-10-26 21:53:55 +00002185 n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002186 xmlNodeSetContent(n, BAD_CAST "abc");
2187 xmlDocSetRootElement(doc, n);
2188 }
2189 }
Daniel Veillard652327a2003-09-29 18:02:38 +00002190#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002191#ifdef LIBXML_HTML_ENABLED
Daniel Veillard73b013f2003-09-30 12:36:01 +00002192#ifdef LIBXML_PUSH_ENABLED
William M. Brack78637da2003-07-31 14:47:38 +00002193 else if ((html) && (push)) {
2194 FILE *f;
2195
Haibo Huangcfd91dc2020-07-30 23:01:33 -07002196 if ((filename[0] == '-') && (filename[1] == 0)) {
2197 f = stdin;
2198 } else {
William M. Brack3403add2004-06-27 02:07:51 +00002199#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
Haibo Huangcfd91dc2020-07-30 23:01:33 -07002200 f = fopen(filename, "rb");
Patrick Monnerat1c43f432013-12-12 15:12:53 +08002201#elif defined(__OS400__)
Haibo Huangcfd91dc2020-07-30 23:01:33 -07002202 f = fopen(filename, "rb");
William M. Brack3403add2004-06-27 02:07:51 +00002203#else
Haibo Huangcfd91dc2020-07-30 23:01:33 -07002204 f = fopen(filename, "r");
William M. Brack3403add2004-06-27 02:07:51 +00002205#endif
Haibo Huangcfd91dc2020-07-30 23:01:33 -07002206 }
William M. Brack78637da2003-07-31 14:47:38 +00002207 if (f != NULL) {
Daniel Veillard1abd2212012-10-25 15:37:50 +08002208 int res;
William M. Brack78637da2003-07-31 14:47:38 +00002209 char chars[4096];
2210 htmlParserCtxtPtr ctxt;
2211
William M. Brack78637da2003-07-31 14:47:38 +00002212 res = fread(chars, 1, 4, f);
2213 if (res > 0) {
2214 ctxt = htmlCreatePushParserCtxt(NULL, NULL,
William M. Brack1d75c8a2003-10-27 13:48:16 +00002215 chars, res, filename, XML_CHAR_ENCODING_NONE);
Elliott Hughes5cefca72021-05-06 13:23:15 -07002216 htmlCtxtUseOptions(ctxt, options);
Daniel Veillard1abd2212012-10-25 15:37:50 +08002217 while ((res = fread(chars, 1, pushsize, f)) > 0) {
William M. Brack78637da2003-07-31 14:47:38 +00002218 htmlParseChunk(ctxt, chars, res, 0);
2219 }
2220 htmlParseChunk(ctxt, chars, 0, 1);
2221 doc = ctxt->myDoc;
2222 htmlFreeParserCtxt(ctxt);
2223 }
2224 fclose(f);
2225 }
2226 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00002227#endif /* LIBXML_PUSH_ENABLED */
Daniel Richard G5706b6d2012-08-06 11:32:54 +08002228#ifdef HAVE_MMAP
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002229 else if ((html) && (memory)) {
2230 int fd;
2231 struct stat info;
2232 const char *base;
Daniel Veillardf1edb102009-08-10 14:43:18 +02002233 if (stat(filename, &info) < 0)
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002234 return;
2235 if ((fd = open(filename, O_RDONLY)) < 0)
2236 return;
2237 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillardb98c6a02013-07-12 12:08:40 +08002238 if (base == (void *) MAP_FAILED) {
2239 close(fd);
2240 fprintf(stderr, "mmap failure for file %s\n", filename);
2241 progresult = XMLLINT_ERR_RDFILE;
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002242 return;
Daniel Veillardb98c6a02013-07-12 12:08:40 +08002243 }
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002244
2245 doc = htmlReadMemory((char *) base, info.st_size, filename,
2246 NULL, options);
Daniel Veillardf1edb102009-08-10 14:43:18 +02002247
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002248 munmap((char *) base, info.st_size);
2249 close(fd);
2250 }
2251#endif
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002252 else if (html) {
Daniel Veillard9475a352003-09-26 12:47:50 +00002253 doc = htmlReadFile(filename, NULL, options);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002254 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002255#endif /* LIBXML_HTML_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002256 else {
Daniel Veillard73b013f2003-09-30 12:36:01 +00002257#ifdef LIBXML_PUSH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002258 /*
2259 * build an XML tree from a string;
2260 */
2261 if (push) {
2262 FILE *f;
2263
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002264 /* '-' Usually means stdin -<sven@zen.org> */
2265 if ((filename[0] == '-') && (filename[1] == 0)) {
2266 f = stdin;
2267 } else {
William M. Brack3403add2004-06-27 02:07:51 +00002268#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2269 f = fopen(filename, "rb");
Patrick Monnerat1c43f432013-12-12 15:12:53 +08002270#elif defined(__OS400__)
2271 f = fopen(filename, "rb");
William M. Brack3403add2004-06-27 02:07:51 +00002272#else
2273 f = fopen(filename, "r");
2274#endif
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002275 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002276 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +00002277 int ret;
Daniel Veillarda880b122003-04-21 21:36:41 +00002278 int res, size = 1024;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002279 char chars[1024];
2280 xmlParserCtxtPtr ctxt;
2281
Daniel Veillarda880b122003-04-21 21:36:41 +00002282 /* if (repeat) size = 1024; */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002283 res = fread(chars, 1, 4, f);
2284 if (res > 0) {
2285 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
2286 chars, res, filename);
Daniel Veillard500a1de2004-03-22 15:22:58 +00002287 xmlCtxtUseOptions(ctxt, options);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002288 while ((res = fread(chars, 1, size, f)) > 0) {
2289 xmlParseChunk(ctxt, chars, res, 0);
2290 }
2291 xmlParseChunk(ctxt, chars, 0, 1);
2292 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +00002293 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002294 xmlFreeParserCtxt(ctxt);
Haibo Huangf0a546b2020-09-01 20:28:19 -07002295 if ((!ret) && (!recovery)) {
Daniel Veillarde715dd22000-08-29 18:29:38 +00002296 xmlFreeDoc(doc);
2297 doc = NULL;
2298 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002299 }
Daniel Veillard84bff682009-09-11 15:30:19 +02002300 if (f != stdin)
2301 fclose(f);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002302 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00002303 } else
2304#endif /* LIBXML_PUSH_ENABLED */
2305 if (testIO) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002306 if ((filename[0] == '-') && (filename[1] == 0)) {
Daniel Veillard60942de2003-09-25 21:05:58 +00002307 doc = xmlReadFd(0, NULL, NULL, options);
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002308 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002309 FILE *f;
Daniel Veillard5e873c42000-04-12 13:27:38 +00002310
William M. Brack3403add2004-06-27 02:07:51 +00002311#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2312 f = fopen(filename, "rb");
Patrick Monnerat1c43f432013-12-12 15:12:53 +08002313#elif defined(__OS400__)
2314 f = fopen(filename, "rb");
William M. Brack3403add2004-06-27 02:07:51 +00002315#else
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002316 f = fopen(filename, "r");
William M. Brack3403add2004-06-27 02:07:51 +00002317#endif
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002318 if (f != NULL) {
2319 if (rectxt == NULL)
Nick Wellnhofer86615e42017-11-09 17:47:47 +01002320 doc = xmlReadIO(myRead, myClose, f, filename, NULL,
2321 options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002322 else
Nick Wellnhofer86615e42017-11-09 17:47:47 +01002323 doc = xmlCtxtReadIO(rectxt, myRead, myClose, f,
2324 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002325 } else
Daniel Veillard5e873c42000-04-12 13:27:38 +00002326 doc = NULL;
Daniel Veillard5e873c42000-04-12 13:27:38 +00002327 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002328 } else if (htmlout) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002329 xmlParserCtxtPtr ctxt;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002330
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002331 if (rectxt == NULL)
2332 ctxt = xmlNewParserCtxt();
2333 else
2334 ctxt = rectxt;
Daniel Veillardf1edb102009-08-10 14:43:18 +02002335 if (ctxt == NULL) {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002336 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +00002337 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002338 ctxt->sax->error = xmlHTMLError;
2339 ctxt->sax->warning = xmlHTMLWarning;
2340 ctxt->vctxt.error = xmlHTMLValidityError;
2341 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002342
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002343 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002344
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002345 if (rectxt == NULL)
2346 xmlFreeParserCtxt(ctxt);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002347 }
Daniel Richard G5706b6d2012-08-06 11:32:54 +08002348#ifdef HAVE_MMAP
Daniel Veillard46e370e2000-07-21 20:32:03 +00002349 } else if (memory) {
2350 int fd;
2351 struct stat info;
2352 const char *base;
Daniel Veillardf1edb102009-08-10 14:43:18 +02002353 if (stat(filename, &info) < 0)
Daniel Veillard46e370e2000-07-21 20:32:03 +00002354 return;
2355 if ((fd = open(filename, O_RDONLY)) < 0)
2356 return;
2357 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillarda75a0092013-05-08 13:45:48 +08002358 if (base == (void *) MAP_FAILED) {
Daniel Veillardb98c6a02013-07-12 12:08:40 +08002359 close(fd);
Daniel Veillarda75a0092013-05-08 13:45:48 +08002360 fprintf(stderr, "mmap failure for file %s\n", filename);
2361 progresult = XMLLINT_ERR_RDFILE;
Daniel Veillard46e370e2000-07-21 20:32:03 +00002362 return;
Daniel Veillarda75a0092013-05-08 13:45:48 +08002363 }
Daniel Veillard46e370e2000-07-21 20:32:03 +00002364
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002365 if (rectxt == NULL)
Daniel Veillard60942de2003-09-25 21:05:58 +00002366 doc = xmlReadMemory((char *) base, info.st_size,
2367 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002368 else
Daniel Veillard60942de2003-09-25 21:05:58 +00002369 doc = xmlCtxtReadMemory(rectxt, (char *) base, info.st_size,
2370 filename, NULL, options);
Daniel Veillardf1edb102009-08-10 14:43:18 +02002371
Daniel Veillard46e370e2000-07-21 20:32:03 +00002372 munmap((char *) base, info.st_size);
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002373 close(fd);
Daniel Veillard46e370e2000-07-21 20:32:03 +00002374#endif
Daniel Veillard4432df22003-09-28 18:58:27 +00002375#ifdef LIBXML_VALID_ENABLED
Daniel Veillardea7751d2002-12-20 00:16:24 +00002376 } else if (valid) {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002377 xmlParserCtxtPtr ctxt = NULL;
Daniel Veillardea7751d2002-12-20 00:16:24 +00002378
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002379 if (rectxt == NULL)
2380 ctxt = xmlNewParserCtxt();
2381 else
2382 ctxt = rectxt;
Daniel Veillardf1edb102009-08-10 14:43:18 +02002383 if (ctxt == NULL) {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002384 doc = NULL;
Daniel Veillardea7751d2002-12-20 00:16:24 +00002385 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002386 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
2387
2388 if (ctxt->valid == 0)
William M. Brack8304d872004-06-08 13:29:32 +00002389 progresult = XMLLINT_ERR_RDFILE;
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002390 if (rectxt == NULL)
2391 xmlFreeParserCtxt(ctxt);
Daniel Veillardea7751d2002-12-20 00:16:24 +00002392 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002393#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardea7751d2002-12-20 00:16:24 +00002394 } else {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002395 if (rectxt != NULL)
2396 doc = xmlCtxtReadFile(rectxt, filename, NULL, options);
Daniel Veillard81562d22005-06-15 13:27:56 +00002397 else {
2398#ifdef LIBXML_SAX1_ENABLED
2399 if (sax1)
2400 doc = xmlParseFile(filename);
2401 else
2402#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002403 doc = xmlReadFile(filename, NULL, options);
Daniel Veillard81562d22005-06-15 13:27:56 +00002404 }
Daniel Veillardea7751d2002-12-20 00:16:24 +00002405 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002406 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002407
Daniel Veillard88a172f2000-08-04 18:23:10 +00002408 /*
2409 * If we don't have a document we might as well give up. Do we
2410 * want an error message here? <sven@zen.org> */
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002411 if (doc == NULL) {
William M. Brack8304d872004-06-08 13:29:32 +00002412 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard88a172f2000-08-04 18:23:10 +00002413 return;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002414 }
2415
Daniel Veillard48b2f892001-02-25 16:11:03 +00002416 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002417 endTimer("Parsing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002418 }
2419
Daniel Veillard29e43992001-12-13 22:21:58 +00002420 /*
2421 * Remove DOCTYPE nodes
2422 */
2423 if (dropdtd) {
2424 xmlDtdPtr dtd;
2425
2426 dtd = xmlGetIntSubset(doc);
2427 if (dtd != NULL) {
2428 xmlUnlinkNode((xmlNodePtr)dtd);
Elliott Hughes5cefca72021-05-06 13:23:15 -07002429 doc->intSubset = NULL;
Daniel Veillard29e43992001-12-13 22:21:58 +00002430 xmlFreeDtd(dtd);
2431 }
2432 }
2433
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002434#ifdef LIBXML_XINCLUDE_ENABLED
Daniel Veillard48b2f892001-02-25 16:11:03 +00002435 if (xinclude) {
2436 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002437 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002438 }
William M. Brack4e1c2db2005-02-11 10:58:55 +00002439 if (xmlXIncludeProcessFlags(doc, options) < 0)
2440 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard48b2f892001-02-25 16:11:03 +00002441 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002442 endTimer("Xinclude processing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002443 }
2444 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002445#endif
Daniel Veillard88a172f2000-08-04 18:23:10 +00002446
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002447#ifdef LIBXML_XPATH_ENABLED
2448 if (xpathquery != NULL) {
2449 doXPathQuery(doc, xpathquery);
2450 }
2451#endif
2452
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002453#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00002454#ifdef LIBXML_XPATH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002455 /*
Daniel Veillardcbaf3992001-12-31 16:16:02 +00002456 * shell interaction
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002457 */
Daniel Veillard26a45c82006-10-20 12:55:34 +00002458 if (shell) {
2459 xmlXPathOrderDocElems(doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002460 xmlShell(doc, filename, xmlShellReadline, stdout);
Daniel Veillard26a45c82006-10-20 12:55:34 +00002461 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002462#endif
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00002463#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002464
Daniel Veillard652327a2003-09-29 18:02:38 +00002465#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002466 /*
2467 * test intermediate copy if needed.
2468 */
2469 if (copy) {
2470 tmp = doc;
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002471 if (timing) {
2472 startTimer();
2473 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002474 doc = xmlCopyDoc(doc, 1);
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002475 if (timing) {
2476 endTimer("Copying");
2477 }
2478 if (timing) {
2479 startTimer();
2480 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002481 xmlFreeDoc(tmp);
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002482 if (timing) {
2483 endTimer("Freeing original");
2484 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002485 }
Daniel Veillard652327a2003-09-29 18:02:38 +00002486#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002487
Daniel Veillard4432df22003-09-28 18:58:27 +00002488#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002489 if ((insert) && (!html)) {
2490 const xmlChar* list[256];
2491 int nb, i;
2492 xmlNodePtr node;
2493
2494 if (doc->children != NULL) {
2495 node = doc->children;
2496 while ((node != NULL) && (node->last == NULL)) node = node->next;
2497 if (node != NULL) {
2498 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
2499 if (nb < 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002500 fprintf(stderr, "could not get valid list of elements\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002501 } else if (nb == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002502 fprintf(stderr, "No element can be inserted under root\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002503 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002504 fprintf(stderr, "%d element types can be inserted under root:\n",
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002505 nb);
2506 for (i = 0;i < nb;i++) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002507 fprintf(stderr, "%s\n", (char *) list[i]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002508 }
2509 }
2510 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02002511 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002512 }else
2513#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002514#ifdef LIBXML_READER_ENABLED
2515 if (walker) {
2516 walkDoc(doc);
2517 }
2518#endif /* LIBXML_READER_ENABLED */
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002519#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard4432df22003-09-28 18:58:27 +00002520 if (noout == 0) {
Daniel Veillard3df01182003-12-10 10:17:51 +00002521 int ret;
2522
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002523 /*
2524 * print it.
2525 */
2526#ifdef LIBXML_DEBUG_ENABLED
2527 if (!debug) {
2528#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00002529 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002530 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002531 }
Daniel Veillard656ce942004-04-30 23:11:45 +00002532#ifdef LIBXML_HTML_ENABLED
Daniel Veillard42fd4122003-11-04 08:47:48 +00002533 if ((html) && (!xmlout)) {
2534 if (compress) {
2535 htmlSaveFile(output ? output : "-", doc);
2536 }
2537 else if (encoding != NULL) {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002538 if (format == 1) {
Daniel Veillard42fd4122003-11-04 08:47:48 +00002539 htmlSaveFileFormat(output ? output : "-", doc, encoding, 1);
2540 }
2541 else {
2542 htmlSaveFileFormat(output ? output : "-", doc, encoding, 0);
2543 }
2544 }
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002545 else if (format == 1) {
Daniel Veillard42fd4122003-11-04 08:47:48 +00002546 htmlSaveFileFormat(output ? output : "-", doc, NULL, 1);
2547 }
2548 else {
2549 FILE *out;
2550 if (output == NULL)
2551 out = stdout;
2552 else {
2553 out = fopen(output,"wb");
2554 }
2555 if (out != NULL) {
2556 if (htmlDocDump(out, doc) < 0)
William M. Brack8304d872004-06-08 13:29:32 +00002557 progresult = XMLLINT_ERR_OUT;
Daniel Veillard42fd4122003-11-04 08:47:48 +00002558
2559 if (output != NULL)
2560 fclose(out);
2561 } else {
2562 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00002563 progresult = XMLLINT_ERR_OUT;
Daniel Veillard42fd4122003-11-04 08:47:48 +00002564 }
2565 }
2566 if ((timing) && (!repeat)) {
2567 endTimer("Saving");
2568 }
2569 } else
2570#endif
Daniel Veillard25048d82004-08-14 22:37:54 +00002571#ifdef LIBXML_C14N_ENABLED
2572 if (canonical) {
2573 xmlChar *result = NULL;
2574 int size;
2575
Aleksey Sanin83868242009-07-09 10:26:22 +02002576 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_0, NULL, 1, &result);
2577 if (size >= 0) {
Stefan Kostdff8d0f2011-05-09 12:14:59 +03002578 if (write(1, result, size) == -1) {
2579 fprintf(stderr, "Can't write data\n");
2580 }
Aleksey Sanin83868242009-07-09 10:26:22 +02002581 xmlFree(result);
2582 } else {
2583 fprintf(stderr, "Failed to canonicalize\n");
2584 progresult = XMLLINT_ERR_OUT;
2585 }
Sérgio Batistad9ea9132014-06-09 22:10:15 +08002586 } else if (canonical_11) {
Aleksey Sanin83868242009-07-09 10:26:22 +02002587 xmlChar *result = NULL;
2588 int size;
2589
2590 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_1, NULL, 1, &result);
Daniel Veillard25048d82004-08-14 22:37:54 +00002591 if (size >= 0) {
Stefan Kostdff8d0f2011-05-09 12:14:59 +03002592 if (write(1, result, size) == -1) {
2593 fprintf(stderr, "Can't write data\n");
2594 }
Daniel Veillard25048d82004-08-14 22:37:54 +00002595 xmlFree(result);
2596 } else {
2597 fprintf(stderr, "Failed to canonicalize\n");
2598 progresult = XMLLINT_ERR_OUT;
2599 }
2600 } else
Aleksey Sanin2650df12005-06-06 17:16:50 +00002601 if (exc_canonical) {
2602 xmlChar *result = NULL;
2603 int size;
2604
Aleksey Sanin83868242009-07-09 10:26:22 +02002605 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_EXCLUSIVE_1_0, NULL, 1, &result);
Aleksey Sanin2650df12005-06-06 17:16:50 +00002606 if (size >= 0) {
Stefan Kostdff8d0f2011-05-09 12:14:59 +03002607 if (write(1, result, size) == -1) {
2608 fprintf(stderr, "Can't write data\n");
2609 }
Aleksey Sanin2650df12005-06-06 17:16:50 +00002610 xmlFree(result);
2611 } else {
2612 fprintf(stderr, "Failed to canonicalize\n");
2613 progresult = XMLLINT_ERR_OUT;
2614 }
2615 } else
Daniel Veillard25048d82004-08-14 22:37:54 +00002616#endif
Daniel Richard G5706b6d2012-08-06 11:32:54 +08002617#ifdef HAVE_MMAP
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002618 if (memory) {
2619 xmlChar *result;
2620 int len;
2621
2622 if (encoding != NULL) {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002623 if (format == 1) {
Daniel Veillardd536f702001-11-08 17:32:47 +00002624 xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
Daniel Veillardf1edb102009-08-10 14:43:18 +02002625 } else {
Daniel Veillardd536f702001-11-08 17:32:47 +00002626 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
2627 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002628 } else {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002629 if (format == 1)
Daniel Veillard90493a92001-08-14 14:12:47 +00002630 xmlDocDumpFormatMemory(doc, &result, &len, 1);
2631 else
2632 xmlDocDumpMemory(doc, &result, &len);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002633 }
2634 if (result == NULL) {
2635 fprintf(stderr, "Failed to save\n");
Daniel Veillard25048d82004-08-14 22:37:54 +00002636 progresult = XMLLINT_ERR_OUT;
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002637 } else {
Stefan Kostdff8d0f2011-05-09 12:14:59 +03002638 if (write(1, result, len) == -1) {
2639 fprintf(stderr, "Can't write data\n");
2640 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002641 xmlFree(result);
2642 }
Daniel Veillarddab39b52006-10-16 23:22:10 +00002643
Daniel Veillard3b2c2612001-04-04 00:09:00 +00002644 } else
Daniel Richard G5706b6d2012-08-06 11:32:54 +08002645#endif /* HAVE_MMAP */
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002646 if (compress) {
2647 xmlSaveFile(output ? output : "-", doc);
Daniel Veillarddab39b52006-10-16 23:22:10 +00002648 } else if (oldout) {
2649 if (encoding != NULL) {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002650 if (format == 1) {
Daniel Veillarddab39b52006-10-16 23:22:10 +00002651 ret = xmlSaveFormatFileEnc(output ? output : "-", doc,
2652 encoding, 1);
2653 }
2654 else {
2655 ret = xmlSaveFileEnc(output ? output : "-", doc,
2656 encoding);
2657 }
2658 if (ret < 0) {
2659 fprintf(stderr, "failed save to %s\n",
2660 output ? output : "-");
2661 progresult = XMLLINT_ERR_OUT;
2662 }
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002663 } else if (format == 1) {
Daniel Veillarddab39b52006-10-16 23:22:10 +00002664 ret = xmlSaveFormatFile(output ? output : "-", doc, 1);
2665 if (ret < 0) {
2666 fprintf(stderr, "failed save to %s\n",
2667 output ? output : "-");
2668 progresult = XMLLINT_ERR_OUT;
2669 }
Daniel Veillard05d987b2003-10-08 11:54:57 +00002670 } else {
Daniel Veillarddab39b52006-10-16 23:22:10 +00002671 FILE *out;
2672 if (output == NULL)
2673 out = stdout;
2674 else {
2675 out = fopen(output,"wb");
2676 }
2677 if (out != NULL) {
2678 if (xmlDocDump(out, doc) < 0)
2679 progresult = XMLLINT_ERR_OUT;
2680
2681 if (output != NULL)
2682 fclose(out);
2683 } else {
2684 fprintf(stderr, "failed to open %s\n", output);
2685 progresult = XMLLINT_ERR_OUT;
2686 }
2687 }
2688 } else {
2689 xmlSaveCtxtPtr ctxt;
2690 int saveOpts = 0;
2691
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002692 if (format == 1)
Daniel Veillarddab39b52006-10-16 23:22:10 +00002693 saveOpts |= XML_SAVE_FORMAT;
Adam Spraggd2e62312010-11-03 15:33:40 +01002694 else if (format == 2)
2695 saveOpts |= XML_SAVE_WSNONSIG;
Daniel Veillard9ccea572010-03-10 15:02:49 +01002696
2697#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
Daniel Veillard9d962642009-08-23 15:31:18 +02002698 if (xmlout)
2699 saveOpts |= XML_SAVE_AS_XML;
Daniel Veillard9ccea572010-03-10 15:02:49 +01002700#endif
Daniel Veillarddab39b52006-10-16 23:22:10 +00002701
2702 if (output == NULL)
2703 ctxt = xmlSaveToFd(1, encoding, saveOpts);
2704 else
2705 ctxt = xmlSaveToFilename(output, encoding, saveOpts);
2706
2707 if (ctxt != NULL) {
2708 if (xmlSaveDoc(ctxt, doc) < 0) {
2709 fprintf(stderr, "failed save to %s\n",
2710 output ? output : "-");
2711 progresult = XMLLINT_ERR_OUT;
2712 }
2713 xmlSaveClose(ctxt);
2714 } else {
William M. Brack8304d872004-06-08 13:29:32 +00002715 progresult = XMLLINT_ERR_OUT;
Daniel Veillard05d987b2003-10-08 11:54:57 +00002716 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002717 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002718 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002719 endTimer("Saving");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002720 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002721#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002722 } else {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002723 FILE *out;
2724 if (output == NULL)
2725 out = stdout;
2726 else {
2727 out = fopen(output,"wb");
2728 }
Daniel Veillard05d987b2003-10-08 11:54:57 +00002729 if (out != NULL) {
2730 xmlDebugDumpDocument(out, doc);
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002731
Daniel Veillard05d987b2003-10-08 11:54:57 +00002732 if (output != NULL)
2733 fclose(out);
2734 } else {
2735 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00002736 progresult = XMLLINT_ERR_OUT;
Daniel Veillard05d987b2003-10-08 11:54:57 +00002737 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002738 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002739#endif
2740 }
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002741#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002742
Daniel Veillard4432df22003-09-28 18:58:27 +00002743#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002744 /*
2745 * A posteriori validation test
2746 */
Daniel Veillard66f68e72003-08-18 16:39:51 +00002747 if ((dtdvalid != NULL) || (dtdvalidfpi != NULL)) {
Daniel Veillardcd429612000-10-11 15:57:05 +00002748 xmlDtdPtr dtd;
2749
Daniel Veillard48b2f892001-02-25 16:11:03 +00002750 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002751 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002752 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00002753 if (dtdvalid != NULL)
Daniel Veillardf1edb102009-08-10 14:43:18 +02002754 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
Daniel Veillard66f68e72003-08-18 16:39:51 +00002755 else
Daniel Veillardf1edb102009-08-10 14:43:18 +02002756 dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL);
Daniel Veillard48b2f892001-02-25 16:11:03 +00002757 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002758 endTimer("Parsing DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002759 }
Daniel Veillardcd429612000-10-11 15:57:05 +00002760 if (dtd == NULL) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00002761 if (dtdvalid != NULL)
2762 xmlGenericError(xmlGenericErrorContext,
2763 "Could not parse DTD %s\n", dtdvalid);
2764 else
2765 xmlGenericError(xmlGenericErrorContext,
2766 "Could not parse DTD %s\n", dtdvalidfpi);
William M. Brack8304d872004-06-08 13:29:32 +00002767 progresult = XMLLINT_ERR_DTD;
Daniel Veillardcd429612000-10-11 15:57:05 +00002768 } else {
Daniel Veillarda37aab82003-06-09 09:10:36 +00002769 xmlValidCtxtPtr cvp;
2770
2771 if ((cvp = xmlNewValidCtxt()) == NULL) {
2772 xmlGenericError(xmlGenericErrorContext,
2773 "Couldn't allocate validation context\n");
2774 exit(-1);
2775 }
Haibo Huangcfd91dc2020-07-30 23:01:33 -07002776 cvp->userData = NULL;
2777 cvp->error = xmlGenericError;
2778 cvp->warning = xmlGenericError;
Daniel Veillarda37aab82003-06-09 09:10:36 +00002779
Daniel Veillard48b2f892001-02-25 16:11:03 +00002780 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002781 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002782 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002783 if (!xmlValidateDtd(cvp, doc, dtd)) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00002784 if (dtdvalid != NULL)
2785 xmlGenericError(xmlGenericErrorContext,
2786 "Document %s does not validate against %s\n",
2787 filename, dtdvalid);
2788 else
2789 xmlGenericError(xmlGenericErrorContext,
2790 "Document %s does not validate against %s\n",
2791 filename, dtdvalidfpi);
William M. Brack8304d872004-06-08 13:29:32 +00002792 progresult = XMLLINT_ERR_VALID;
Daniel Veillardcd429612000-10-11 15:57:05 +00002793 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002794 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002795 endTimer("Validating against DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002796 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002797 xmlFreeValidCtxt(cvp);
Daniel Veillardcd429612000-10-11 15:57:05 +00002798 xmlFreeDtd(dtd);
2799 }
2800 } else if (postvalid) {
Daniel Veillarda37aab82003-06-09 09:10:36 +00002801 xmlValidCtxtPtr cvp;
2802
2803 if ((cvp = xmlNewValidCtxt()) == NULL) {
2804 xmlGenericError(xmlGenericErrorContext,
2805 "Couldn't allocate validation context\n");
2806 exit(-1);
2807 }
2808
Daniel Veillard48b2f892001-02-25 16:11:03 +00002809 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002810 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002811 }
Haibo Huangcfd91dc2020-07-30 23:01:33 -07002812 cvp->userData = NULL;
2813 cvp->error = xmlGenericError;
2814 cvp->warning = xmlGenericError;
Daniel Veillarda37aab82003-06-09 09:10:36 +00002815 if (!xmlValidateDocument(cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00002816 xmlGenericError(xmlGenericErrorContext,
2817 "Document %s does not validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002818 progresult = XMLLINT_ERR_VALID;
Daniel Veillardcd429612000-10-11 15:57:05 +00002819 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002820 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002821 endTimer("Validating");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002822 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002823 xmlFreeValidCtxt(cvp);
Daniel Veillard4432df22003-09-28 18:58:27 +00002824 }
2825#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardd4501d72005-07-24 14:27:16 +00002826#ifdef LIBXML_SCHEMATRON_ENABLED
2827 if (wxschematron != NULL) {
2828 xmlSchematronValidCtxtPtr ctxt;
2829 int ret;
Daniel Veillardc740a172005-07-31 12:17:24 +00002830 int flag;
Daniel Veillardd4501d72005-07-24 14:27:16 +00002831
2832 if ((timing) && (!repeat)) {
2833 startTimer();
2834 }
2835
2836 if (debug)
2837 flag = XML_SCHEMATRON_OUT_XML;
Daniel Veillardc740a172005-07-31 12:17:24 +00002838 else
2839 flag = XML_SCHEMATRON_OUT_TEXT;
2840 if (noout)
2841 flag |= XML_SCHEMATRON_OUT_QUIET;
Daniel Veillardd4501d72005-07-24 14:27:16 +00002842 ctxt = xmlSchematronNewValidCtxt(wxschematron, flag);
2843#if 0
Haibo Huangcfd91dc2020-07-30 23:01:33 -07002844 xmlSchematronSetValidErrors(ctxt, xmlGenericError, xmlGenericError,
2845 NULL);
Daniel Veillardd4501d72005-07-24 14:27:16 +00002846#endif
2847 ret = xmlSchematronValidateDoc(ctxt, doc);
2848 if (ret == 0) {
Haibo Huang735158e2021-02-23 17:48:08 -08002849 if (!quiet) {
2850 fprintf(stderr, "%s validates\n", filename);
2851 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00002852 } else if (ret > 0) {
2853 fprintf(stderr, "%s fails to validate\n", filename);
2854 progresult = XMLLINT_ERR_VALID;
2855 } else {
2856 fprintf(stderr, "%s validation generated an internal error\n",
2857 filename);
2858 progresult = XMLLINT_ERR_VALID;
2859 }
2860 xmlSchematronFreeValidCtxt(ctxt);
2861 if ((timing) && (!repeat)) {
2862 endTimer("Validating");
2863 }
2864 }
2865#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00002866#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard4432df22003-09-28 18:58:27 +00002867 if (relaxngschemas != NULL) {
Daniel Veillard71531f32003-02-05 13:19:53 +00002868 xmlRelaxNGValidCtxtPtr ctxt;
2869 int ret;
2870
Daniel Veillard42f12e92003-03-07 18:32:59 +00002871 if ((timing) && (!repeat)) {
2872 startTimer();
2873 }
2874
Daniel Veillard71531f32003-02-05 13:19:53 +00002875 ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
Haibo Huangcfd91dc2020-07-30 23:01:33 -07002876 xmlRelaxNGSetValidErrors(ctxt, xmlGenericError, xmlGenericError, NULL);
Daniel Veillard71531f32003-02-05 13:19:53 +00002877 ret = xmlRelaxNGValidateDoc(ctxt, doc);
2878 if (ret == 0) {
Haibo Huang735158e2021-02-23 17:48:08 -08002879 if (!quiet) {
2880 fprintf(stderr, "%s validates\n", filename);
2881 }
Daniel Veillard71531f32003-02-05 13:19:53 +00002882 } else if (ret > 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002883 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002884 progresult = XMLLINT_ERR_VALID;
Daniel Veillard71531f32003-02-05 13:19:53 +00002885 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002886 fprintf(stderr, "%s validation generated an internal error\n",
Daniel Veillard71531f32003-02-05 13:19:53 +00002887 filename);
William M. Brack8304d872004-06-08 13:29:32 +00002888 progresult = XMLLINT_ERR_VALID;
Daniel Veillard71531f32003-02-05 13:19:53 +00002889 }
2890 xmlRelaxNGFreeValidCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00002891 if ((timing) && (!repeat)) {
2892 endTimer("Validating");
2893 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002894 } else if (wxschemas != NULL) {
2895 xmlSchemaValidCtxtPtr ctxt;
2896 int ret;
2897
2898 if ((timing) && (!repeat)) {
2899 startTimer();
2900 }
2901
2902 ctxt = xmlSchemaNewValidCtxt(wxschemas);
Haibo Huangcfd91dc2020-07-30 23:01:33 -07002903 xmlSchemaSetValidErrors(ctxt, xmlGenericError, xmlGenericError, NULL);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002904 ret = xmlSchemaValidateDoc(ctxt, doc);
2905 if (ret == 0) {
Haibo Huang735158e2021-02-23 17:48:08 -08002906 if (!quiet) {
2907 fprintf(stderr, "%s validates\n", filename);
2908 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002909 } else if (ret > 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002910 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002911 progresult = XMLLINT_ERR_VALID;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002912 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002913 fprintf(stderr, "%s validation generated an internal error\n",
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002914 filename);
William M. Brack8304d872004-06-08 13:29:32 +00002915 progresult = XMLLINT_ERR_VALID;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002916 }
2917 xmlSchemaFreeValidCtxt(ctxt);
2918 if ((timing) && (!repeat)) {
2919 endTimer("Validating");
2920 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002921 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002922#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002923
2924#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillard6b099012008-11-06 13:47:39 +00002925#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002926 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00002927 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002928#endif
Daniel Veillard6b099012008-11-06 13:47:39 +00002929#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002930
2931 /*
2932 * free it.
2933 */
Daniel Veillard48b2f892001-02-25 16:11:03 +00002934 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002935 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002936 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002937 xmlFreeDoc(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +00002938 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002939 endTimer("Freeing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002940 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002941}
2942
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002943/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +02002944 * *
2945 * Usage and Main *
2946 * *
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002947 ************************************************************************/
2948
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002949static void showVersion(const char *name) {
2950 fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
2951 fprintf(stderr, " compiled with: ");
Daniel Veillard602434d2005-09-12 09:20:31 +00002952 if (xmlHasFeature(XML_WITH_THREAD)) fprintf(stderr, "Threads ");
2953 if (xmlHasFeature(XML_WITH_TREE)) fprintf(stderr, "Tree ");
2954 if (xmlHasFeature(XML_WITH_OUTPUT)) fprintf(stderr, "Output ");
2955 if (xmlHasFeature(XML_WITH_PUSH)) fprintf(stderr, "Push ");
2956 if (xmlHasFeature(XML_WITH_READER)) fprintf(stderr, "Reader ");
2957 if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(stderr, "Patterns ");
2958 if (xmlHasFeature(XML_WITH_WRITER)) fprintf(stderr, "Writer ");
2959 if (xmlHasFeature(XML_WITH_SAX1)) fprintf(stderr, "SAXv1 ");
Daniel Veillardf1edb102009-08-10 14:43:18 +02002960 if (xmlHasFeature(XML_WITH_FTP)) fprintf(stderr, "FTP ");
2961 if (xmlHasFeature(XML_WITH_HTTP)) fprintf(stderr, "HTTP ");
Daniel Veillard602434d2005-09-12 09:20:31 +00002962 if (xmlHasFeature(XML_WITH_VALID)) fprintf(stderr, "DTDValid ");
Daniel Veillardf1edb102009-08-10 14:43:18 +02002963 if (xmlHasFeature(XML_WITH_HTML)) fprintf(stderr, "HTML ");
2964 if (xmlHasFeature(XML_WITH_LEGACY)) fprintf(stderr, "Legacy ");
2965 if (xmlHasFeature(XML_WITH_C14N)) fprintf(stderr, "C14N ");
2966 if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(stderr, "Catalog ");
2967 if (xmlHasFeature(XML_WITH_XPATH)) fprintf(stderr, "XPath ");
2968 if (xmlHasFeature(XML_WITH_XPTR)) fprintf(stderr, "XPointer ");
2969 if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(stderr, "XInclude ");
2970 if (xmlHasFeature(XML_WITH_ICONV)) fprintf(stderr, "Iconv ");
David Kilzer783931f2016-03-02 12:48:51 -08002971 if (xmlHasFeature(XML_WITH_ICU)) fprintf(stderr, "ICU ");
Daniel Veillardf1edb102009-08-10 14:43:18 +02002972 if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(stderr, "ISO8859X ");
2973 if (xmlHasFeature(XML_WITH_UNICODE)) fprintf(stderr, "Unicode ");
2974 if (xmlHasFeature(XML_WITH_REGEXP)) fprintf(stderr, "Regexps ");
2975 if (xmlHasFeature(XML_WITH_AUTOMATA)) fprintf(stderr, "Automata ");
2976 if (xmlHasFeature(XML_WITH_EXPR)) fprintf(stderr, "Expr ");
2977 if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(stderr, "Schemas ");
2978 if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(stderr, "Schematron ");
2979 if (xmlHasFeature(XML_WITH_MODULES)) fprintf(stderr, "Modules ");
2980 if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(stderr, "Debug ");
2981 if (xmlHasFeature(XML_WITH_DEBUG_MEM)) fprintf(stderr, "MemDebug ");
2982 if (xmlHasFeature(XML_WITH_DEBUG_RUN)) fprintf(stderr, "RunDebug ");
Daniel Veillard75acfee2006-07-13 06:29:56 +00002983 if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(stderr, "Zlib ");
Anders F Bjorklundeae52612011-09-18 16:59:13 +02002984 if (xmlHasFeature(XML_WITH_LZMA)) fprintf(stderr, "Lzma ");
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002985 fprintf(stderr, "\n");
2986}
2987
Nick Wellnhoferf4353652017-06-20 16:19:33 +02002988static void usage(FILE *f, const char *name) {
2989 fprintf(f, "Usage : %s [options] XMLfiles ...\n", name);
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002990#ifdef LIBXML_OUTPUT_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02002991 fprintf(f, "\tParse the XML files and output the result of the parsing\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002992#else
Nick Wellnhoferf4353652017-06-20 16:19:33 +02002993 fprintf(f, "\tParse the XML files\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002994#endif /* LIBXML_OUTPUT_ENABLED */
Nick Wellnhoferf4353652017-06-20 16:19:33 +02002995 fprintf(f, "\t--version : display the version of the XML library used\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002996#ifdef LIBXML_DEBUG_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02002997 fprintf(f, "\t--debug : dump a debug tree of the in-memory document\n");
2998 fprintf(f, "\t--shell : run a navigating shell\n");
2999 fprintf(f, "\t--debugent : debug the entities defined in the document\n");
Daniel Veillard8326e732003-01-07 00:19:07 +00003000#else
Daniel Veillard81273902003-09-30 00:43:48 +00003001#ifdef LIBXML_READER_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003002 fprintf(f, "\t--debug : dump the nodes content when using --stream\n");
Daniel Veillard81273902003-09-30 00:43:48 +00003003#endif /* LIBXML_READER_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003004#endif
Daniel Veillard652327a2003-09-29 18:02:38 +00003005#ifdef LIBXML_TREE_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003006 fprintf(f, "\t--copy : used to test the internal copy implementation\n");
Daniel Veillard652327a2003-09-29 18:02:38 +00003007#endif /* LIBXML_TREE_ENABLED */
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003008 fprintf(f, "\t--recover : output what was parsable on broken XML documents\n");
3009 fprintf(f, "\t--huge : remove any internal arbitrary parser limits\n");
3010 fprintf(f, "\t--noent : substitute entity references by their value\n");
3011 fprintf(f, "\t--noenc : ignore any encoding specified inside the document\n");
3012 fprintf(f, "\t--noout : don't output the result tree\n");
3013 fprintf(f, "\t--path 'paths': provide a set of paths for resources\n");
3014 fprintf(f, "\t--load-trace : print trace of all external entities loaded\n");
3015 fprintf(f, "\t--nonet : refuse to fetch DTDs or entities over network\n");
3016 fprintf(f, "\t--nocompact : do not generate compact text nodes\n");
3017 fprintf(f, "\t--htmlout : output results as HTML\n");
3018 fprintf(f, "\t--nowrap : do not put HTML doc wrapper\n");
Daniel Veillard4432df22003-09-28 18:58:27 +00003019#ifdef LIBXML_VALID_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003020 fprintf(f, "\t--valid : validate the document in addition to std well-formed check\n");
3021 fprintf(f, "\t--postvalid : do a posteriori validation, i.e after parsing\n");
3022 fprintf(f, "\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
3023 fprintf(f, "\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
Daniel Veillard4432df22003-09-28 18:58:27 +00003024#endif /* LIBXML_VALID_ENABLED */
Haibo Huang735158e2021-02-23 17:48:08 -08003025 fprintf(f, "\t--quiet : be quiet when succeeded\n");
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003026 fprintf(f, "\t--timing : print some timings\n");
3027 fprintf(f, "\t--output file or -o file: save to a given file\n");
3028 fprintf(f, "\t--repeat : repeat 100 times, for timing or profiling\n");
3029 fprintf(f, "\t--insert : ad-hoc test for valid insertions\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003030#ifdef LIBXML_OUTPUT_ENABLED
Nick Wellnhofercb5541c2017-11-13 17:08:38 +01003031#ifdef LIBXML_ZLIB_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003032 fprintf(f, "\t--compress : turn on gzip compression of output\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003033#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003034#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003035#ifdef LIBXML_HTML_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003036 fprintf(f, "\t--html : use the HTML parser\n");
3037 fprintf(f, "\t--xmlout : force to use the XML serializer when using --html\n");
3038 fprintf(f, "\t--nodefdtd : do not default HTML doctype\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003039#endif
Daniel Veillard73b013f2003-09-30 12:36:01 +00003040#ifdef LIBXML_PUSH_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003041 fprintf(f, "\t--push : use the push mode of the parser\n");
3042 fprintf(f, "\t--pushsmall : use the push mode of the parser using tiny increments\n");
Daniel Veillard73b013f2003-09-30 12:36:01 +00003043#endif /* LIBXML_PUSH_ENABLED */
Daniel Richard G5706b6d2012-08-06 11:32:54 +08003044#ifdef HAVE_MMAP
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003045 fprintf(f, "\t--memory : parse from memory\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003046#endif
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003047 fprintf(f, "\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n");
3048 fprintf(f, "\t--nowarning : do not emit warnings from parser/validator\n");
3049 fprintf(f, "\t--noblanks : drop (ignorable?) blanks spaces\n");
3050 fprintf(f, "\t--nocdata : replace cdata section with text nodes\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003051#ifdef LIBXML_OUTPUT_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003052 fprintf(f, "\t--format : reformat/reindent the output\n");
3053 fprintf(f, "\t--encode encoding : output in the given encoding\n");
3054 fprintf(f, "\t--dropdtd : remove the DOCTYPE of the input docs\n");
3055 fprintf(f, "\t--pretty STYLE : pretty-print in a particular style\n");
3056 fprintf(f, "\t 0 Do not pretty print\n");
3057 fprintf(f, "\t 1 Format the XML content, as --format\n");
3058 fprintf(f, "\t 2 Add whitespace inside tags, preserving content\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003059#endif /* LIBXML_OUTPUT_ENABLED */
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003060 fprintf(f, "\t--c14n : save in W3C canonical format v1.0 (with comments)\n");
3061 fprintf(f, "\t--c14n11 : save in W3C canonical format v1.1 (with comments)\n");
3062 fprintf(f, "\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n");
Daniel Veillard25048d82004-08-14 22:37:54 +00003063#ifdef LIBXML_C14N_ENABLED
3064#endif /* LIBXML_C14N_ENABLED */
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003065 fprintf(f, "\t--nsclean : remove redundant namespace declarations\n");
3066 fprintf(f, "\t--testIO : test user I/O support\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003067#ifdef LIBXML_CATALOG_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003068 fprintf(f, "\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
3069 fprintf(f, "\t otherwise XML Catalogs starting from \n");
3070 fprintf(f, "\t %s are activated by default\n", XML_XML_DEFAULT_CATALOG);
3071 fprintf(f, "\t--nocatalogs: deactivate all catalogs\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003072#endif
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003073 fprintf(f, "\t--auto : generate a small doc on the fly\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003074#ifdef LIBXML_XINCLUDE_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003075 fprintf(f, "\t--xinclude : do XInclude processing\n");
3076 fprintf(f, "\t--noxincludenode : same but do not generate XInclude nodes\n");
3077 fprintf(f, "\t--nofixup-base-uris : do not fixup xml:base uris\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003078#endif
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003079 fprintf(f, "\t--loaddtd : fetch external DTD\n");
3080 fprintf(f, "\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
Daniel Veillard81273902003-09-30 00:43:48 +00003081#ifdef LIBXML_READER_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003082 fprintf(f, "\t--stream : use the streaming interface to process very large files\n");
3083 fprintf(f, "\t--walker : create a reader and walk though the resulting doc\n");
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003084#ifdef LIBXML_PATTERN_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003085 fprintf(f, "\t--pattern pattern_value : test the pattern support\n");
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003086#endif
Haibo Huangcfd91dc2020-07-30 23:01:33 -07003087#endif /* LIBXML_READER_ENABLED */
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003088 fprintf(f, "\t--chkregister : verify the node registration code\n");
Daniel Veillardef4d3bc2003-02-07 12:38:22 +00003089#ifdef LIBXML_SCHEMAS_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003090 fprintf(f, "\t--relaxng schema : do RelaxNG validation against the schema\n");
3091 fprintf(f, "\t--schema schema : do validation against the WXS schema\n");
Daniel Veillard71531f32003-02-05 13:19:53 +00003092#endif
Daniel Veillarde70375c2005-07-30 21:09:12 +00003093#ifdef LIBXML_SCHEMATRON_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003094 fprintf(f, "\t--schematron schema : do validation against a schematron\n");
Daniel Veillarde70375c2005-07-30 21:09:12 +00003095#endif
Daniel Veillard971771e2005-07-09 17:32:57 +00003096#ifdef LIBXML_SAX1_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003097 fprintf(f, "\t--sax1: use the old SAX1 interfaces for processing\n");
Daniel Veillard971771e2005-07-09 17:32:57 +00003098#endif
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003099 fprintf(f, "\t--sax: do not build a tree but work just at the SAX level\n");
3100 fprintf(f, "\t--oldxml10: use XML-1.0 parsing rules before the 5th edition\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003101#ifdef LIBXML_XPATH_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003102 fprintf(f, "\t--xpath expr: evaluate the XPath expression, imply --noout\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003103#endif
Daniel Veillard971771e2005-07-09 17:32:57 +00003104
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003105 fprintf(f, "\nLibxml project home page: http://xmlsoft.org/\n");
3106 fprintf(f, "To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003107}
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003108
3109static void registerNode(xmlNodePtr node)
3110{
3111 node->_private = malloc(sizeof(long));
Daniel Veillarde71dce12013-07-11 15:41:22 +08003112 if (node->_private == NULL) {
3113 fprintf(stderr, "Out of memory in xmllint:registerNode()\n");
3114 exit(XMLLINT_ERR_MEM);
3115 }
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003116 *(long*)node->_private = (long) 0x81726354;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003117 nbregister++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003118}
3119
3120static void deregisterNode(xmlNodePtr node)
3121{
3122 assert(node->_private != NULL);
3123 assert(*(long*)node->_private == (long) 0x81726354);
3124 free(node->_private);
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003125 nbregister--;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003126}
3127
Daniel Veillard4a6845d2001-01-03 13:32:39 +00003128int
3129main(int argc, char **argv) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00003130 int i, acount;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003131 int files = 0;
Daniel Veillard845cce42002-01-09 11:51:37 +00003132 int version = 0;
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00003133 const char* indent;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003134
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003135 if (argc <= 1) {
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003136 usage(stderr, argv[0]);
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003137 return(1);
3138 }
Daniel Veillardbe803962000-06-28 23:40:59 +00003139 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003140 for (i = 1; i < argc ; i++) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003141 if (!strcmp(argv[i], "-"))
3142 break;
3143
3144 if (argv[i][0] != '-')
3145 continue;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003146 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
3147 debug++;
Daniel Veillard56ada1d2003-01-07 11:17:25 +00003148 else
3149#ifdef LIBXML_DEBUG_ENABLED
3150 if ((!strcmp(argv[i], "-shell")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003151 (!strcmp(argv[i], "--shell"))) {
3152 shell++;
3153 noout = 1;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003154 } else
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003155#endif
Daniel Veillard652327a2003-09-29 18:02:38 +00003156#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003157 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
3158 copy++;
Daniel Veillard652327a2003-09-29 18:02:38 +00003159 else
3160#endif /* LIBXML_TREE_ENABLED */
3161 if ((!strcmp(argv[i], "-recover")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003162 (!strcmp(argv[i], "--recover"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003163 recovery++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003164 options |= XML_PARSE_RECOVER;
Daniel Veillard8915c152008-08-26 13:05:34 +00003165 } else if ((!strcmp(argv[i], "-huge")) ||
3166 (!strcmp(argv[i], "--huge"))) {
3167 options |= XML_PARSE_HUGE;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003168 } else if ((!strcmp(argv[i], "-noent")) ||
3169 (!strcmp(argv[i], "--noent"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003170 noent++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003171 options |= XML_PARSE_NOENT;
Daniel Veillardc62efc82011-05-16 16:03:50 +08003172 } else if ((!strcmp(argv[i], "-noenc")) ||
3173 (!strcmp(argv[i], "--noenc"))) {
3174 noenc++;
3175 options |= XML_PARSE_IGNORE_ENC;
Daniel Veillarddca8cc72003-09-26 13:53:14 +00003176 } else if ((!strcmp(argv[i], "-nsclean")) ||
3177 (!strcmp(argv[i], "--nsclean"))) {
3178 options |= XML_PARSE_NSCLEAN;
3179 } else if ((!strcmp(argv[i], "-nocdata")) ||
3180 (!strcmp(argv[i], "--nocdata"))) {
3181 options |= XML_PARSE_NOCDATA;
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003182 } else if ((!strcmp(argv[i], "-nodict")) ||
3183 (!strcmp(argv[i], "--nodict"))) {
3184 options |= XML_PARSE_NODICT;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003185 } else if ((!strcmp(argv[i], "-version")) ||
Daniel Veillard845cce42002-01-09 11:51:37 +00003186 (!strcmp(argv[i], "--version"))) {
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00003187 showVersion(argv[0]);
Daniel Veillard845cce42002-01-09 11:51:37 +00003188 version = 1;
3189 } else if ((!strcmp(argv[i], "-noout")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003190 (!strcmp(argv[i], "--noout")))
3191 noout++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003192#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003193 else if ((!strcmp(argv[i], "-o")) ||
3194 (!strcmp(argv[i], "-output")) ||
3195 (!strcmp(argv[i], "--output"))) {
3196 i++;
Daniel Veillard6e4f1c02002-04-09 09:55:20 +00003197 output = argv[i];
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003198 }
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003199#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003200 else if ((!strcmp(argv[i], "-htmlout")) ||
3201 (!strcmp(argv[i], "--htmlout")))
3202 htmlout++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003203 else if ((!strcmp(argv[i], "-nowrap")) ||
3204 (!strcmp(argv[i], "--nowrap")))
3205 nowrap++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003206#ifdef LIBXML_HTML_ENABLED
3207 else if ((!strcmp(argv[i], "-html")) ||
3208 (!strcmp(argv[i], "--html"))) {
3209 html++;
3210 }
Daniel Veillard42fd4122003-11-04 08:47:48 +00003211 else if ((!strcmp(argv[i], "-xmlout")) ||
3212 (!strcmp(argv[i], "--xmlout"))) {
3213 xmlout++;
Daniel Veillardf1121c42010-07-26 14:02:42 +02003214 } else if ((!strcmp(argv[i], "-nodefdtd")) ||
3215 (!strcmp(argv[i], "--nodefdtd"))) {
3216 nodefdtd++;
3217 options |= HTML_PARSE_NODEFDTD;
Daniel Veillard42fd4122003-11-04 08:47:48 +00003218 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003219#endif /* LIBXML_HTML_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003220 else if ((!strcmp(argv[i], "-loaddtd")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003221 (!strcmp(argv[i], "--loaddtd"))) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003222 loaddtd++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003223 options |= XML_PARSE_DTDLOAD;
3224 } else if ((!strcmp(argv[i], "-dtdattr")) ||
Daniel Veillard48da9102001-08-07 01:10:10 +00003225 (!strcmp(argv[i], "--dtdattr"))) {
3226 loaddtd++;
3227 dtdattrs++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003228 options |= XML_PARSE_DTDATTR;
Daniel Veillard4432df22003-09-28 18:58:27 +00003229 }
3230#ifdef LIBXML_VALID_ENABLED
3231 else if ((!strcmp(argv[i], "-valid")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003232 (!strcmp(argv[i], "--valid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003233 valid++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003234 options |= XML_PARSE_DTDVALID;
3235 } else if ((!strcmp(argv[i], "-postvalid")) ||
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003236 (!strcmp(argv[i], "--postvalid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003237 postvalid++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003238 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003239 options |= XML_PARSE_DTDLOAD;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003240 } else if ((!strcmp(argv[i], "-dtdvalid")) ||
Daniel Veillardcd429612000-10-11 15:57:05 +00003241 (!strcmp(argv[i], "--dtdvalid"))) {
3242 i++;
3243 dtdvalid = argv[i];
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003244 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003245 options |= XML_PARSE_DTDLOAD;
Daniel Veillard66f68e72003-08-18 16:39:51 +00003246 } else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3247 (!strcmp(argv[i], "--dtdvalidfpi"))) {
3248 i++;
3249 dtdvalidfpi = argv[i];
3250 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003251 options |= XML_PARSE_DTDLOAD;
Daniel Veillardcd429612000-10-11 15:57:05 +00003252 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003253#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard29e43992001-12-13 22:21:58 +00003254 else if ((!strcmp(argv[i], "-dropdtd")) ||
3255 (!strcmp(argv[i], "--dropdtd")))
3256 dropdtd++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003257 else if ((!strcmp(argv[i], "-insert")) ||
3258 (!strcmp(argv[i], "--insert")))
3259 insert++;
Haibo Huang735158e2021-02-23 17:48:08 -08003260 else if ((!strcmp(argv[i], "-quiet")) ||
3261 (!strcmp(argv[i], "--quiet")))
3262 quiet++;
Daniel Veillard48b2f892001-02-25 16:11:03 +00003263 else if ((!strcmp(argv[i], "-timing")) ||
3264 (!strcmp(argv[i], "--timing")))
3265 timing++;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00003266 else if ((!strcmp(argv[i], "-auto")) ||
3267 (!strcmp(argv[i], "--auto")))
3268 generate++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003269 else if ((!strcmp(argv[i], "-repeat")) ||
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00003270 (!strcmp(argv[i], "--repeat"))) {
3271 if (repeat)
3272 repeat *= 10;
3273 else
3274 repeat = 100;
Daniel Veillard73b013f2003-09-30 12:36:01 +00003275 }
3276#ifdef LIBXML_PUSH_ENABLED
3277 else if ((!strcmp(argv[i], "-push")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003278 (!strcmp(argv[i], "--push")))
3279 push++;
Daniel Veillard1abd2212012-10-25 15:37:50 +08003280 else if ((!strcmp(argv[i], "-pushsmall")) ||
3281 (!strcmp(argv[i], "--pushsmall"))) {
3282 push++;
3283 pushsize = 10;
3284 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00003285#endif /* LIBXML_PUSH_ENABLED */
Daniel Richard G5706b6d2012-08-06 11:32:54 +08003286#ifdef HAVE_MMAP
Daniel Veillard46e370e2000-07-21 20:32:03 +00003287 else if ((!strcmp(argv[i], "-memory")) ||
3288 (!strcmp(argv[i], "--memory")))
3289 memory++;
3290#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +00003291 else if ((!strcmp(argv[i], "-testIO")) ||
3292 (!strcmp(argv[i], "--testIO")))
3293 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003294#ifdef LIBXML_XINCLUDE_ENABLED
3295 else if ((!strcmp(argv[i], "-xinclude")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003296 (!strcmp(argv[i], "--xinclude"))) {
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003297 xinclude++;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003298 options |= XML_PARSE_XINCLUDE;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003299 }
Daniel Veillardc14c3892004-08-16 12:34:50 +00003300 else if ((!strcmp(argv[i], "-noxincludenode")) ||
3301 (!strcmp(argv[i], "--noxincludenode"))) {
3302 xinclude++;
3303 options |= XML_PARSE_XINCLUDE;
3304 options |= XML_PARSE_NOXINCNODE;
3305 }
Daniel Veillard54bd29b2008-08-26 07:26:55 +00003306 else if ((!strcmp(argv[i], "-nofixup-base-uris")) ||
3307 (!strcmp(argv[i], "--nofixup-base-uris"))) {
3308 xinclude++;
3309 options |= XML_PARSE_XINCLUDE;
3310 options |= XML_PARSE_NOBASEFIX;
3311 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003312#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003313#ifdef LIBXML_OUTPUT_ENABLED
Nick Wellnhofercb5541c2017-11-13 17:08:38 +01003314#ifdef LIBXML_ZLIB_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003315 else if ((!strcmp(argv[i], "-compress")) ||
3316 (!strcmp(argv[i], "--compress"))) {
3317 compress++;
3318 xmlSetCompressMode(9);
3319 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003320#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003321#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003322 else if ((!strcmp(argv[i], "-nowarning")) ||
3323 (!strcmp(argv[i], "--nowarning"))) {
3324 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003325 xmlPedanticParserDefault(0);
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003326 options |= XML_PARSE_NOWARNING;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003327 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003328 else if ((!strcmp(argv[i], "-pedantic")) ||
3329 (!strcmp(argv[i], "--pedantic"))) {
3330 xmlGetWarningsDefaultValue = 1;
3331 xmlPedanticParserDefault(1);
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003332 options |= XML_PARSE_PEDANTIC;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003333 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00003334#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003335 else if ((!strcmp(argv[i], "-debugent")) ||
3336 (!strcmp(argv[i], "--debugent"))) {
3337 debugent++;
3338 xmlParserDebugEntities = 1;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003339 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00003340#endif
Daniel Veillard25048d82004-08-14 22:37:54 +00003341#ifdef LIBXML_C14N_ENABLED
3342 else if ((!strcmp(argv[i], "-c14n")) ||
3343 (!strcmp(argv[i], "--c14n"))) {
3344 canonical++;
3345 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003346 }
Aleksey Sanin83868242009-07-09 10:26:22 +02003347 else if ((!strcmp(argv[i], "-c14n11")) ||
3348 (!strcmp(argv[i], "--c14n11"))) {
3349 canonical_11++;
3350 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003351 }
Aleksey Sanin2650df12005-06-06 17:16:50 +00003352 else if ((!strcmp(argv[i], "-exc-c14n")) ||
3353 (!strcmp(argv[i], "--exc-c14n"))) {
3354 exc_canonical++;
3355 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003356 }
Daniel Veillard25048d82004-08-14 22:37:54 +00003357#endif
Daniel Veillard81418e32001-05-22 15:08:55 +00003358#ifdef LIBXML_CATALOG_ENABLED
3359 else if ((!strcmp(argv[i], "-catalogs")) ||
3360 (!strcmp(argv[i], "--catalogs"))) {
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003361 catalogs++;
3362 } else if ((!strcmp(argv[i], "-nocatalogs")) ||
3363 (!strcmp(argv[i], "--nocatalogs"))) {
3364 nocatalogs++;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003365 }
Daniel Veillard81418e32001-05-22 15:08:55 +00003366#endif
Daniel Veillardbe803962000-06-28 23:40:59 +00003367 else if ((!strcmp(argv[i], "-encode")) ||
3368 (!strcmp(argv[i], "--encode"))) {
3369 i++;
3370 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003371 /*
3372 * OK it's for testing purposes
3373 */
3374 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +00003375 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003376 else if ((!strcmp(argv[i], "-noblanks")) ||
3377 (!strcmp(argv[i], "--noblanks"))) {
Daniel Veillardf933c892012-09-07 19:32:12 +08003378 noblanks++;
3379 xmlKeepBlanksDefault(0);
3380 options |= XML_PARSE_NOBLANKS;
Daniel Veillard90493a92001-08-14 14:12:47 +00003381 }
Daniel Veillard87076042004-05-03 22:54:49 +00003382 else if ((!strcmp(argv[i], "-maxmem")) ||
3383 (!strcmp(argv[i], "--maxmem"))) {
3384 i++;
3385 if (sscanf(argv[i], "%d", &maxmem) == 1) {
3386 xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc,
3387 myStrdupFunc);
3388 } else {
3389 maxmem = 0;
3390 }
3391 }
Daniel Veillard90493a92001-08-14 14:12:47 +00003392 else if ((!strcmp(argv[i], "-format")) ||
3393 (!strcmp(argv[i], "--format"))) {
3394 noblanks++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003395#ifdef LIBXML_OUTPUT_ENABLED
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01003396 format = 1;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003397#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard90493a92001-08-14 14:12:47 +00003398 xmlKeepBlanksDefault(0);
Daniel Veillard7704fb12003-01-03 16:19:51 +00003399 }
Adam Spraggd2e62312010-11-03 15:33:40 +01003400 else if ((!strcmp(argv[i], "-pretty")) ||
3401 (!strcmp(argv[i], "--pretty"))) {
3402 i++;
3403#ifdef LIBXML_OUTPUT_ENABLED
Tim Galeckas2205ff42013-08-29 16:44:33 +08003404 if (argv[i] != NULL) {
3405 format = atoi(argv[i]);
3406 if (format == 1) {
3407 noblanks++;
3408 xmlKeepBlanksDefault(0);
3409 }
3410 }
Brandon Slack0c7109c2012-05-11 10:50:59 +08003411#endif /* LIBXML_OUTPUT_ENABLED */
Adam Spraggd2e62312010-11-03 15:33:40 +01003412 }
Daniel Veillard81273902003-09-30 00:43:48 +00003413#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003414 else if ((!strcmp(argv[i], "-stream")) ||
3415 (!strcmp(argv[i], "--stream"))) {
3416 stream++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003417 }
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003418 else if ((!strcmp(argv[i], "-walker")) ||
3419 (!strcmp(argv[i], "--walker"))) {
3420 walker++;
3421 noout++;
Haibo Huangcfd91dc2020-07-30 23:01:33 -07003422#ifdef LIBXML_PATTERN_ENABLED
3423 } else if ((!strcmp(argv[i], "-pattern")) ||
3424 (!strcmp(argv[i], "--pattern"))) {
3425 i++;
3426 pattern = argv[i];
3427#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003428 }
Daniel Veillard81273902003-09-30 00:43:48 +00003429#endif /* LIBXML_READER_ENABLED */
3430#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +00003431 else if ((!strcmp(argv[i], "-sax1")) ||
3432 (!strcmp(argv[i], "--sax1"))) {
Daniel Veillard023d0ba2009-07-29 11:34:50 +02003433 sax1++;
3434 options |= XML_PARSE_SAX1;
Daniel Veillard07cb8222003-09-10 10:51:05 +00003435 }
Daniel Veillard81273902003-09-30 00:43:48 +00003436#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003437 else if ((!strcmp(argv[i], "-sax")) ||
3438 (!strcmp(argv[i], "--sax"))) {
Daniel Veillard023d0ba2009-07-29 11:34:50 +02003439 sax++;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003440 }
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003441 else if ((!strcmp(argv[i], "-chkregister")) ||
3442 (!strcmp(argv[i], "--chkregister"))) {
Daniel Veillard023d0ba2009-07-29 11:34:50 +02003443 chkregister++;
Daniel Veillard71531f32003-02-05 13:19:53 +00003444#ifdef LIBXML_SCHEMAS_ENABLED
3445 } else if ((!strcmp(argv[i], "-relaxng")) ||
3446 (!strcmp(argv[i], "--relaxng"))) {
3447 i++;
3448 relaxng = argv[i];
3449 noent++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003450 options |= XML_PARSE_NOENT;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003451 } else if ((!strcmp(argv[i], "-schema")) ||
3452 (!strcmp(argv[i], "--schema"))) {
3453 i++;
3454 schema = argv[i];
3455 noent++;
Daniel Veillard71531f32003-02-05 13:19:53 +00003456#endif
Daniel Veillardd4501d72005-07-24 14:27:16 +00003457#ifdef LIBXML_SCHEMATRON_ENABLED
3458 } else if ((!strcmp(argv[i], "-schematron")) ||
3459 (!strcmp(argv[i], "--schematron"))) {
3460 i++;
3461 schematron = argv[i];
3462 noent++;
3463#endif
Daniel Veillarde8b09e42003-05-13 22:14:13 +00003464 } else if ((!strcmp(argv[i], "-nonet")) ||
3465 (!strcmp(argv[i], "--nonet"))) {
Daniel Veillard61b93382003-11-03 14:28:31 +00003466 options |= XML_PARSE_NONET;
Daniel Veillard968d6432006-04-25 16:17:53 +00003467 xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
Daniel Veillard8874b942005-08-25 13:19:21 +00003468 } else if ((!strcmp(argv[i], "-nocompact")) ||
3469 (!strcmp(argv[i], "--nocompact"))) {
3470 options &= ~XML_PARSE_COMPACT;
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003471 } else if ((!strcmp(argv[i], "-load-trace")) ||
3472 (!strcmp(argv[i], "--load-trace"))) {
3473 load_trace++;
3474 } else if ((!strcmp(argv[i], "-path")) ||
3475 (!strcmp(argv[i], "--path"))) {
3476 i++;
3477 parsePath(BAD_CAST argv[i]);
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003478#ifdef LIBXML_XPATH_ENABLED
3479 } else if ((!strcmp(argv[i], "-xpath")) ||
3480 (!strcmp(argv[i], "--xpath"))) {
3481 i++;
3482 noout++;
3483 xpathquery = argv[i];
3484#endif
Daniel Veillard7e5c3f42008-07-29 16:12:31 +00003485 } else if ((!strcmp(argv[i], "-oldxml10")) ||
3486 (!strcmp(argv[i], "--oldxml10"))) {
3487 oldxml10++;
3488 options |= XML_PARSE_OLD10;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003489 } else {
3490 fprintf(stderr, "Unknown option %s\n", argv[i]);
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003491 usage(stderr, argv[0]);
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003492 return(1);
3493 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003494 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003495
3496#ifdef LIBXML_CATALOG_ENABLED
3497 if (nocatalogs == 0) {
3498 if (catalogs) {
3499 const char *catal;
3500
3501 catal = getenv("SGML_CATALOG_FILES");
Daniel Veillard6c5f9d12001-08-25 13:33:14 +00003502 if (catal != NULL) {
3503 xmlLoadCatalogs(catal);
3504 } else {
3505 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
3506 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003507 }
3508 }
3509#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003510
Daniel Veillard81273902003-09-30 00:43:48 +00003511#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +00003512 if (sax1)
3513 xmlSAXDefaultVersion(1);
3514 else
3515 xmlSAXDefaultVersion(2);
Daniel Veillard81273902003-09-30 00:43:48 +00003516#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillard07cb8222003-09-10 10:51:05 +00003517
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003518 if (chkregister) {
3519 xmlRegisterNodeDefault(registerNode);
3520 xmlDeregisterNodeDefault(deregisterNode);
3521 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02003522
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00003523 indent = getenv("XMLLINT_INDENT");
3524 if(indent != NULL) {
3525 xmlTreeIndentString = indent;
3526 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02003527
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003528
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003529 defaultEntityLoader = xmlGetExternalEntityLoader();
3530 xmlSetExternalEntityLoader(xmllintExternalEntityLoader);
3531
Daniel Veillardd9bad132001-07-23 19:39:43 +00003532 xmlLineNumbersDefault(1);
Daniel Veillard48da9102001-08-07 01:10:10 +00003533 if (loaddtd != 0)
3534 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
3535 if (dtdattrs)
3536 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003537 if (noent != 0) xmlSubstituteEntitiesDefault(1);
Daniel Veillard4432df22003-09-28 18:58:27 +00003538#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003539 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
Daniel Veillard4432df22003-09-28 18:58:27 +00003540#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003541 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003542 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003543 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003544 xmlGenericError(xmlGenericErrorContext,
3545 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
3546 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003547 "<html><head><title>%s output</title></head>\n",
3548 argv[0]);
Daniel Veillardf1edb102009-08-10 14:43:18 +02003549 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003550 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
3551 argv[0]);
3552 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003553
Daniel Veillardd4501d72005-07-24 14:27:16 +00003554#ifdef LIBXML_SCHEMATRON_ENABLED
3555 if ((schematron != NULL) && (sax == 0)
3556#ifdef LIBXML_READER_ENABLED
3557 && (stream == 0)
3558#endif /* LIBXML_READER_ENABLED */
3559 ) {
3560 xmlSchematronParserCtxtPtr ctxt;
3561
3562 /* forces loading the DTDs */
Daniel Veillardf1edb102009-08-10 14:43:18 +02003563 xmlLoadExtDtdDefaultValue |= 1;
Daniel Veillardd4501d72005-07-24 14:27:16 +00003564 options |= XML_PARSE_DTDLOAD;
3565 if (timing) {
3566 startTimer();
3567 }
3568 ctxt = xmlSchematronNewParserCtxt(schematron);
3569#if 0
Haibo Huangcfd91dc2020-07-30 23:01:33 -07003570 xmlSchematronSetParserErrors(ctxt, xmlGenericError, xmlGenericError,
3571 NULL);
Daniel Veillardd4501d72005-07-24 14:27:16 +00003572#endif
3573 wxschematron = xmlSchematronParse(ctxt);
3574 if (wxschematron == NULL) {
3575 xmlGenericError(xmlGenericErrorContext,
3576 "Schematron schema %s failed to compile\n", schematron);
3577 progresult = XMLLINT_ERR_SCHEMACOMP;
3578 schematron = NULL;
3579 }
3580 xmlSchematronFreeParserCtxt(ctxt);
3581 if (timing) {
3582 endTimer("Compiling the schemas");
3583 }
3584 }
3585#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00003586#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003587 if ((relaxng != NULL) && (sax == 0)
Daniel Veillard81273902003-09-30 00:43:48 +00003588#ifdef LIBXML_READER_ENABLED
3589 && (stream == 0)
3590#endif /* LIBXML_READER_ENABLED */
3591 ) {
Daniel Veillard71531f32003-02-05 13:19:53 +00003592 xmlRelaxNGParserCtxtPtr ctxt;
3593
Daniel Veillardce192eb2003-04-16 15:58:05 +00003594 /* forces loading the DTDs */
Daniel Veillardf1edb102009-08-10 14:43:18 +02003595 xmlLoadExtDtdDefaultValue |= 1;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003596 options |= XML_PARSE_DTDLOAD;
Daniel Veillard42f12e92003-03-07 18:32:59 +00003597 if (timing) {
3598 startTimer();
3599 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003600 ctxt = xmlRelaxNGNewParserCtxt(relaxng);
Haibo Huangcfd91dc2020-07-30 23:01:33 -07003601 xmlRelaxNGSetParserErrors(ctxt, xmlGenericError, xmlGenericError,
3602 NULL);
Daniel Veillard71531f32003-02-05 13:19:53 +00003603 relaxngschemas = xmlRelaxNGParse(ctxt);
Daniel Veillardce192eb2003-04-16 15:58:05 +00003604 if (relaxngschemas == NULL) {
3605 xmlGenericError(xmlGenericErrorContext,
3606 "Relax-NG schema %s failed to compile\n", relaxng);
William M. Brack8304d872004-06-08 13:29:32 +00003607 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillardce192eb2003-04-16 15:58:05 +00003608 relaxng = NULL;
3609 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003610 xmlRelaxNGFreeParserCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00003611 if (timing) {
3612 endTimer("Compiling the schemas");
3613 }
Daniel Veillardebe25d42004-03-25 09:35:49 +00003614 } else if ((schema != NULL)
3615#ifdef LIBXML_READER_ENABLED
Daniel Veillardf10ae122005-07-10 19:03:16 +00003616 && (stream == 0)
Daniel Veillardebe25d42004-03-25 09:35:49 +00003617#endif
3618 ) {
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003619 xmlSchemaParserCtxtPtr ctxt;
3620
3621 if (timing) {
3622 startTimer();
3623 }
3624 ctxt = xmlSchemaNewParserCtxt(schema);
Haibo Huangcfd91dc2020-07-30 23:01:33 -07003625 xmlSchemaSetParserErrors(ctxt, xmlGenericError, xmlGenericError, NULL);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003626 wxschemas = xmlSchemaParse(ctxt);
3627 if (wxschemas == NULL) {
3628 xmlGenericError(xmlGenericErrorContext,
3629 "WXS schema %s failed to compile\n", schema);
William M. Brack8304d872004-06-08 13:29:32 +00003630 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003631 schema = NULL;
3632 }
3633 xmlSchemaFreeParserCtxt(ctxt);
3634 if (timing) {
3635 endTimer("Compiling the schemas");
3636 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003637 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003638#endif /* LIBXML_SCHEMAS_ENABLED */
Haibo Huangcfd91dc2020-07-30 23:01:33 -07003639#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
3640 if ((pattern != NULL) && (walker == 0)) {
Daniel Veillardffa7b7e2003-12-05 16:10:21 +00003641 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003642 if (patternc == NULL) {
3643 xmlGenericError(xmlGenericErrorContext,
3644 "Pattern %s failed to compile\n", pattern);
William M. Brack8304d872004-06-08 13:29:32 +00003645 progresult = XMLLINT_ERR_SCHEMAPAT;
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003646 pattern = NULL;
3647 }
3648 }
Haibo Huangcfd91dc2020-07-30 23:01:33 -07003649#endif /* LIBXML_READER_ENABLED && LIBXML_PATTERN_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003650 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +00003651 if ((!strcmp(argv[i], "-encode")) ||
3652 (!strcmp(argv[i], "--encode"))) {
3653 i++;
3654 continue;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003655 } else if ((!strcmp(argv[i], "-o")) ||
3656 (!strcmp(argv[i], "-output")) ||
3657 (!strcmp(argv[i], "--output"))) {
3658 i++;
3659 continue;
Daniel Veillardbe803962000-06-28 23:40:59 +00003660 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003661#ifdef LIBXML_VALID_ENABLED
Daniel Veillardcd429612000-10-11 15:57:05 +00003662 if ((!strcmp(argv[i], "-dtdvalid")) ||
3663 (!strcmp(argv[i], "--dtdvalid"))) {
3664 i++;
3665 continue;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003666 }
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003667 if ((!strcmp(argv[i], "-path")) ||
3668 (!strcmp(argv[i], "--path"))) {
3669 i++;
3670 continue;
Daniel Veillardcd429612000-10-11 15:57:05 +00003671 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00003672 if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3673 (!strcmp(argv[i], "--dtdvalidfpi"))) {
3674 i++;
3675 continue;
3676 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003677#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard71531f32003-02-05 13:19:53 +00003678 if ((!strcmp(argv[i], "-relaxng")) ||
3679 (!strcmp(argv[i], "--relaxng"))) {
3680 i++;
3681 continue;
3682 }
Daniel Veillard87076042004-05-03 22:54:49 +00003683 if ((!strcmp(argv[i], "-maxmem")) ||
3684 (!strcmp(argv[i], "--maxmem"))) {
3685 i++;
3686 continue;
3687 }
Adam Spraggd2e62312010-11-03 15:33:40 +01003688 if ((!strcmp(argv[i], "-pretty")) ||
3689 (!strcmp(argv[i], "--pretty"))) {
3690 i++;
3691 continue;
3692 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003693 if ((!strcmp(argv[i], "-schema")) ||
3694 (!strcmp(argv[i], "--schema"))) {
3695 i++;
3696 continue;
3697 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00003698 if ((!strcmp(argv[i], "-schematron")) ||
3699 (!strcmp(argv[i], "--schematron"))) {
3700 i++;
3701 continue;
3702 }
Haibo Huangcfd91dc2020-07-30 23:01:33 -07003703#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003704 if ((!strcmp(argv[i], "-pattern")) ||
3705 (!strcmp(argv[i], "--pattern"))) {
3706 i++;
3707 continue;
3708 }
3709#endif
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003710#ifdef LIBXML_XPATH_ENABLED
3711 if ((!strcmp(argv[i], "-xpath")) ||
3712 (!strcmp(argv[i], "--xpath"))) {
3713 i++;
3714 continue;
3715 }
3716#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00003717 if ((timing) && (repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00003718 startTimer();
Daniel Veillardcbaf3992001-12-31 16:16:02 +00003719 /* Remember file names. "-" means stdin. <sven@zen.org> */
Daniel Veillard4a6845d2001-01-03 13:32:39 +00003720 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003721 if (repeat) {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003722 xmlParserCtxtPtr ctxt = NULL;
3723
3724 for (acount = 0;acount < repeat;acount++) {
Daniel Veillard81273902003-09-30 00:43:48 +00003725#ifdef LIBXML_READER_ENABLED
Daniel Veillard198c1bf2003-10-20 17:07:41 +00003726 if (stream != 0) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00003727 streamFile(argv[i]);
Daniel Veillard198c1bf2003-10-20 17:07:41 +00003728 } else {
Daniel Veillard81273902003-09-30 00:43:48 +00003729#endif /* LIBXML_READER_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003730 if (sax) {
3731 testSAX(argv[i]);
3732 } else {
3733 if (ctxt == NULL)
3734 ctxt = xmlNewParserCtxt();
3735 parseAndPrintFile(argv[i], ctxt);
3736 }
Daniel Veillard81273902003-09-30 00:43:48 +00003737#ifdef LIBXML_READER_ENABLED
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003738 }
Daniel Veillard81273902003-09-30 00:43:48 +00003739#endif /* LIBXML_READER_ENABLED */
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003740 }
3741 if (ctxt != NULL)
3742 xmlFreeParserCtxt(ctxt);
Daniel Veillard7704fb12003-01-03 16:19:51 +00003743 } else {
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003744 nbregister = 0;
3745
Daniel Veillard81273902003-09-30 00:43:48 +00003746#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003747 if (stream != 0)
3748 streamFile(argv[i]);
3749 else
Daniel Veillard81273902003-09-30 00:43:48 +00003750#endif /* LIBXML_READER_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003751 if (sax) {
3752 testSAX(argv[i]);
3753 } else {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003754 parseAndPrintFile(argv[i], NULL);
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003755 }
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003756
3757 if ((chkregister) && (nbregister != 0)) {
3758 fprintf(stderr, "Registration count off: %d\n", nbregister);
William M. Brack8304d872004-06-08 13:29:32 +00003759 progresult = XMLLINT_ERR_RDREGIS;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003760 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00003761 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003762 files ++;
Daniel Veillarda7866932001-12-04 13:14:44 +00003763 if ((timing) && (repeat)) {
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00003764 endTimer("%d iterations", repeat);
Daniel Veillarda7866932001-12-04 13:14:44 +00003765 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00003766 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003767 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02003768 if (generate)
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003769 parseAndPrintFile(NULL, NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003770 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003771 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003772 }
Daniel Veillard845cce42002-01-09 11:51:37 +00003773 if ((files == 0) && (!generate) && (version == 0)) {
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003774 usage(stderr, argv[0]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003775 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00003776#ifdef LIBXML_SCHEMATRON_ENABLED
3777 if (wxschematron != NULL)
3778 xmlSchematronFree(wxschematron);
3779#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00003780#ifdef LIBXML_SCHEMAS_ENABLED
3781 if (relaxngschemas != NULL)
3782 xmlRelaxNGFree(relaxngschemas);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003783 if (wxschemas != NULL)
3784 xmlSchemaFree(wxschemas);
Daniel Veillard71531f32003-02-05 13:19:53 +00003785 xmlRelaxNGCleanupTypes();
3786#endif
Haibo Huangcfd91dc2020-07-30 23:01:33 -07003787#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003788 if (patternc != NULL)
3789 xmlFreePattern(patternc);
3790#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003791 xmlCleanupParser();
3792 xmlMemoryDump();
3793
Daniel Veillardf7cd4812001-02-23 18:44:52 +00003794 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003795}
Daniel Veillard88a172f2000-08-04 18:23:10 +00003796