blob: b314189f5d52ecf0c1f2d1e8a6ea652f2f595a06 [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);
Elliott Hughesecdab2a2022-02-23 14:33:50 -08001662 if (vctxt == NULL) {
1663 progresult = XMLLINT_ERR_MEM;
1664 xmlFreeParserInputBuffer(buf);
1665 goto error;
1666 }
Haibo Huangcfd91dc2020-07-30 23:01:33 -07001667 xmlSchemaSetValidErrors(vctxt, xmlGenericError, xmlGenericError, NULL);
Daniel Veillard97fa5b32012-08-14 11:01:07 +08001668 xmlSchemaValidateSetFilename(vctxt, filename);
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001669
Daniel Veillard971771e2005-07-09 17:32:57 +00001670 ret = xmlSchemaValidateStream(vctxt, buf, 0, handler,
1671 (void *)user_data);
1672 if (repeat == 0) {
1673 if (ret == 0) {
Haibo Huang735158e2021-02-23 17:48:08 -08001674 if (!quiet) {
1675 fprintf(stderr, "%s validates\n", filename);
1676 }
Daniel Veillard971771e2005-07-09 17:32:57 +00001677 } else if (ret > 0) {
1678 fprintf(stderr, "%s fails to validate\n", filename);
1679 progresult = XMLLINT_ERR_VALID;
1680 } else {
1681 fprintf(stderr, "%s validation generated an internal error\n",
1682 filename);
1683 progresult = XMLLINT_ERR_VALID;
1684 }
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001685 }
1686 xmlSchemaFreeValidCtxt(vctxt);
1687 } else
1688#endif
1689 {
1690 /*
1691 * Create the parser context amd hook the input
1692 */
1693 ctxt = xmlNewParserCtxt();
1694 if (ctxt == NULL) {
Elliott Hughesecdab2a2022-02-23 14:33:50 -08001695 progresult = XMLLINT_ERR_MEM;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001696 xmlFreeParserInputBuffer(buf);
1697 goto error;
1698 }
1699 old_sax = ctxt->sax;
1700 ctxt->sax = handler;
1701 ctxt->userData = (void *) user_data;
1702 inputStream = xmlNewIOInputStream(ctxt, buf, XML_CHAR_ENCODING_NONE);
1703 if (inputStream == NULL) {
1704 xmlFreeParserInputBuffer(buf);
1705 goto error;
1706 }
1707 inputPush(ctxt, inputStream);
Daniel Veillardf1edb102009-08-10 14:43:18 +02001708
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001709 /* do the parsing */
1710 xmlParseDocument(ctxt);
1711
1712 if (ctxt->myDoc != NULL) {
1713 fprintf(stderr, "SAX generated a doc !\n");
1714 xmlFreeDoc(ctxt->myDoc);
1715 ctxt->myDoc = NULL;
1716 }
1717 }
1718
1719error:
1720 if (ctxt != NULL) {
1721 ctxt->sax = old_sax;
1722 xmlFreeParserCtxt(ctxt);
1723 }
1724}
1725
Daniel Veillard5e873c42000-04-12 13:27:38 +00001726/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +02001727 * *
1728 * Stream Test processing *
1729 * *
Daniel Veillard7704fb12003-01-03 16:19:51 +00001730 ************************************************************************/
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001731#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00001732static void processNode(xmlTextReaderPtr reader) {
Daniel Veillard198c1bf2003-10-20 17:07:41 +00001733 const xmlChar *name, *value;
Daniel Veillard16ef8002005-01-31 00:27:50 +00001734 int type, empty;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001735
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001736 type = xmlTextReaderNodeType(reader);
Daniel Veillard16ef8002005-01-31 00:27:50 +00001737 empty = xmlTextReaderIsEmptyElement(reader);
Daniel Veillard99737f52003-03-22 14:55:50 +00001738
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001739 if (debug) {
1740 name = xmlTextReaderConstName(reader);
1741 if (name == NULL)
1742 name = BAD_CAST "--";
Daniel Veillard7704fb12003-01-03 16:19:51 +00001743
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001744 value = xmlTextReaderConstValue(reader);
1745
Daniel Veillardf1edb102009-08-10 14:43:18 +02001746
1747 printf("%d %d %s %d %d",
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001748 xmlTextReaderDepth(reader),
1749 type,
1750 name,
Daniel Veillard16ef8002005-01-31 00:27:50 +00001751 empty,
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001752 xmlTextReaderHasValue(reader));
1753 if (value == NULL)
1754 printf("\n");
1755 else {
1756 printf(" %s\n", value);
1757 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001758 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001759#ifdef LIBXML_PATTERN_ENABLED
1760 if (patternc) {
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001761 xmlChar *path = NULL;
1762 int match = -1;
Daniel Veillardf1edb102009-08-10 14:43:18 +02001763
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001764 if (type == XML_READER_TYPE_ELEMENT) {
1765 /* do the check only on element start */
1766 match = xmlPatternMatch(patternc, xmlTextReaderCurrentNode(reader));
1767
1768 if (match) {
Daniel Veillardf1edb102009-08-10 14:43:18 +02001769#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001770 path = xmlGetNodePath(xmlTextReaderCurrentNode(reader));
1771 printf("Node %s matches pattern %s\n", path, pattern);
Daniel Veillardf1edb102009-08-10 14:43:18 +02001772#else
1773 printf("Node %s matches pattern %s\n",
1774 xmlTextReaderConstName(reader), pattern);
1775#endif
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001776 }
1777 }
1778 if (patstream != NULL) {
1779 int ret;
1780
1781 if (type == XML_READER_TYPE_ELEMENT) {
1782 ret = xmlStreamPush(patstream,
1783 xmlTextReaderConstLocalName(reader),
1784 xmlTextReaderConstNamespaceUri(reader));
1785 if (ret < 0) {
1786 fprintf(stderr, "xmlStreamPush() failure\n");
1787 xmlFreeStreamCtxt(patstream);
1788 patstream = NULL;
1789 } else if (ret != match) {
Daniel Veillardf1edb102009-08-10 14:43:18 +02001790#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001791 if (path == NULL) {
1792 path = xmlGetNodePath(
1793 xmlTextReaderCurrentNode(reader));
1794 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02001795#endif
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001796 fprintf(stderr,
1797 "xmlPatternMatch and xmlStreamPush disagree\n");
Daniel Veillardf1edb102009-08-10 14:43:18 +02001798 if (path != NULL)
1799 fprintf(stderr, " pattern %s node %s\n",
1800 pattern, path);
1801 else
1802 fprintf(stderr, " pattern %s node %s\n",
1803 pattern, xmlTextReaderConstName(reader));
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001804 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001805
Daniel Veillardf1edb102009-08-10 14:43:18 +02001806 }
Daniel Veillard16ef8002005-01-31 00:27:50 +00001807 if ((type == XML_READER_TYPE_END_ELEMENT) ||
1808 ((type == XML_READER_TYPE_ELEMENT) && (empty))) {
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001809 ret = xmlStreamPop(patstream);
1810 if (ret < 0) {
1811 fprintf(stderr, "xmlStreamPop() failure\n");
1812 xmlFreeStreamCtxt(patstream);
1813 patstream = NULL;
1814 }
1815 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001816 }
Daniel Veillardf9d16912005-01-30 22:36:30 +00001817 if (path != NULL)
1818 xmlFree(path);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001819 }
1820#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001821}
1822
1823static void streamFile(char *filename) {
1824 xmlTextReaderPtr reader;
1825 int ret;
Daniel Richard G5706b6d2012-08-06 11:32:54 +08001826#ifdef HAVE_MMAP
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001827 int fd = -1;
1828 struct stat info;
1829 const char *base = NULL;
1830 xmlParserInputBufferPtr input = NULL;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001831
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001832 if (memory) {
Daniel Veillardf1edb102009-08-10 14:43:18 +02001833 if (stat(filename, &info) < 0)
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001834 return;
1835 if ((fd = open(filename, O_RDONLY)) < 0)
1836 return;
1837 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillardb98c6a02013-07-12 12:08:40 +08001838 if (base == (void *) MAP_FAILED) {
1839 close(fd);
1840 fprintf(stderr, "mmap failure for file %s\n", filename);
1841 progresult = XMLLINT_ERR_RDFILE;
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001842 return;
Daniel Veillardb98c6a02013-07-12 12:08:40 +08001843 }
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001844
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001845 reader = xmlReaderForMemory(base, info.st_size, filename,
1846 NULL, options);
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001847 } else
1848#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001849 reader = xmlReaderForFile(filename, NULL, options);
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001850#ifdef LIBXML_PATTERN_ENABLED
Daniel Veillardd4301ab2005-02-03 22:24:10 +00001851 if (pattern != NULL) {
1852 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
1853 if (patternc == NULL) {
1854 xmlGenericError(xmlGenericErrorContext,
1855 "Pattern %s failed to compile\n", pattern);
1856 progresult = XMLLINT_ERR_SCHEMAPAT;
1857 pattern = NULL;
1858 }
1859 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001860 if (patternc != NULL) {
1861 patstream = xmlPatternGetStreamCtxt(patternc);
1862 if (patstream != NULL) {
1863 ret = xmlStreamPush(patstream, NULL, NULL);
1864 if (ret < 0) {
1865 fprintf(stderr, "xmlStreamPush() failure\n");
1866 xmlFreeStreamCtxt(patstream);
1867 patstream = NULL;
1868 }
1869 }
1870 }
1871#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001872
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001873
Daniel Veillard7704fb12003-01-03 16:19:51 +00001874 if (reader != NULL) {
Daniel Veillard4432df22003-09-28 18:58:27 +00001875#ifdef LIBXML_VALID_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00001876 if (valid)
1877 xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
Daniel Veillardce192eb2003-04-16 15:58:05 +00001878 else
Daniel Veillard4432df22003-09-28 18:58:27 +00001879#endif /* LIBXML_VALID_ENABLED */
Daniel Veillarde4d16d72012-12-21 10:58:14 +08001880 if (loaddtd)
1881 xmlTextReaderSetParserProp(reader, XML_PARSER_LOADDTD, 1);
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001882#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +00001883 if (relaxng != NULL) {
Daniel Veillard81514ba2003-09-16 23:17:26 +00001884 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001885 startTimer();
1886 }
1887 ret = xmlTextReaderRelaxNGValidate(reader, relaxng);
1888 if (ret < 0) {
1889 xmlGenericError(xmlGenericErrorContext,
1890 "Relax-NG schema %s failed to compile\n", relaxng);
William M. Brack8304d872004-06-08 13:29:32 +00001891 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillardce192eb2003-04-16 15:58:05 +00001892 relaxng = NULL;
1893 }
Daniel Veillard81514ba2003-09-16 23:17:26 +00001894 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001895 endTimer("Compiling the schemas");
1896 }
1897 }
Daniel Veillardf10ae122005-07-10 19:03:16 +00001898 if (schema != NULL) {
1899 if ((timing) && (!repeat)) {
1900 startTimer();
1901 }
1902 ret = xmlTextReaderSchemaValidate(reader, schema);
1903 if (ret < 0) {
1904 xmlGenericError(xmlGenericErrorContext,
1905 "XSD schema %s failed to compile\n", schema);
1906 progresult = XMLLINT_ERR_SCHEMACOMP;
1907 schema = NULL;
1908 }
1909 if ((timing) && (!repeat)) {
1910 endTimer("Compiling the schemas");
1911 }
1912 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001913#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001914
1915 /*
1916 * Process all nodes in sequence
1917 */
Daniel Veillard81514ba2003-09-16 23:17:26 +00001918 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001919 startTimer();
1920 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001921 ret = xmlTextReaderRead(reader);
1922 while (ret == 1) {
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001923 if ((debug)
1924#ifdef LIBXML_PATTERN_ENABLED
1925 || (patternc)
1926#endif
1927 )
Daniel Veillard7704fb12003-01-03 16:19:51 +00001928 processNode(reader);
1929 ret = xmlTextReaderRead(reader);
1930 }
Daniel Veillard81514ba2003-09-16 23:17:26 +00001931 if ((timing) && (!repeat)) {
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001932#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf54cd532004-02-25 11:52:31 +00001933 if (relaxng != NULL)
Daniel Veillard49138f12004-02-19 12:58:36 +00001934 endTimer("Parsing and validating");
1935 else
Daniel Veillardf54cd532004-02-25 11:52:31 +00001936#endif
Daniel Veillard4432df22003-09-28 18:58:27 +00001937#ifdef LIBXML_VALID_ENABLED
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001938 if (valid)
Daniel Veillardce192eb2003-04-16 15:58:05 +00001939 endTimer("Parsing and validating");
1940 else
Daniel Veillard4432df22003-09-28 18:58:27 +00001941#endif
Daniel Veillardf54cd532004-02-25 11:52:31 +00001942 endTimer("Parsing");
Daniel Veillardce192eb2003-04-16 15:58:05 +00001943 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001944
Daniel Veillard4432df22003-09-28 18:58:27 +00001945#ifdef LIBXML_VALID_ENABLED
Daniel Veillardf6bad792003-04-11 19:38:54 +00001946 if (valid) {
1947 if (xmlTextReaderIsValid(reader) != 1) {
1948 xmlGenericError(xmlGenericErrorContext,
1949 "Document %s does not validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001950 progresult = XMLLINT_ERR_VALID;
Daniel Veillardf6bad792003-04-11 19:38:54 +00001951 }
1952 }
Daniel Veillard4432df22003-09-28 18:58:27 +00001953#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001954#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf10ae122005-07-10 19:03:16 +00001955 if ((relaxng != NULL) || (schema != NULL)) {
Daniel Veillardf4e55762003-04-15 23:32:22 +00001956 if (xmlTextReaderIsValid(reader) != 1) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001957 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001958 progresult = XMLLINT_ERR_VALID;
Daniel Veillardf4e55762003-04-15 23:32:22 +00001959 } else {
Haibo Huang735158e2021-02-23 17:48:08 -08001960 if (!quiet) {
1961 fprintf(stderr, "%s validates\n", filename);
1962 }
Daniel Veillardf4e55762003-04-15 23:32:22 +00001963 }
1964 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001965#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001966 /*
1967 * Done, cleanup and status
1968 */
1969 xmlFreeTextReader(reader);
1970 if (ret != 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001971 fprintf(stderr, "%s : failed to parse\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001972 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001973 }
1974 } else {
1975 fprintf(stderr, "Unable to open %s\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001976 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001977 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001978#ifdef LIBXML_PATTERN_ENABLED
1979 if (patstream != NULL) {
1980 xmlFreeStreamCtxt(patstream);
1981 patstream = NULL;
1982 }
1983#endif
Daniel Richard G5706b6d2012-08-06 11:32:54 +08001984#ifdef HAVE_MMAP
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001985 if (memory) {
1986 xmlFreeParserInputBuffer(input);
1987 munmap((char *) base, info.st_size);
1988 close(fd);
1989 }
1990#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001991}
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001992
1993static void walkDoc(xmlDocPtr doc) {
1994 xmlTextReaderPtr reader;
1995 int ret;
1996
Daniel Veillardd4301ab2005-02-03 22:24:10 +00001997#ifdef LIBXML_PATTERN_ENABLED
1998 xmlNodePtr root;
1999 const xmlChar *namespaces[22];
2000 int i;
2001 xmlNsPtr ns;
2002
2003 root = xmlDocGetRootElement(doc);
Hugh Davenportb8e0fa32016-05-04 10:55:49 +08002004 if (root == NULL ) {
2005 xmlGenericError(xmlGenericErrorContext,
2006 "Document does not have a root element");
2007 progresult = XMLLINT_ERR_UNCLASS;
2008 return;
2009 }
Daniel Veillardd4301ab2005-02-03 22:24:10 +00002010 for (ns = root->nsDef, i = 0;ns != NULL && i < 20;ns=ns->next) {
2011 namespaces[i++] = ns->href;
2012 namespaces[i++] = ns->prefix;
2013 }
2014 namespaces[i++] = NULL;
Daniel Veillard13cee4e2009-09-05 14:52:55 +02002015 namespaces[i] = NULL;
Daniel Veillardd4301ab2005-02-03 22:24:10 +00002016
2017 if (pattern != NULL) {
2018 patternc = xmlPatterncompile((const xmlChar *) pattern, doc->dict,
2019 0, &namespaces[0]);
2020 if (patternc == NULL) {
2021 xmlGenericError(xmlGenericErrorContext,
2022 "Pattern %s failed to compile\n", pattern);
2023 progresult = XMLLINT_ERR_SCHEMAPAT;
2024 pattern = NULL;
2025 }
2026 }
Daniel Veillard2b2e02d2005-02-05 23:20:22 +00002027 if (patternc != NULL) {
2028 patstream = xmlPatternGetStreamCtxt(patternc);
2029 if (patstream != NULL) {
2030 ret = xmlStreamPush(patstream, NULL, NULL);
2031 if (ret < 0) {
2032 fprintf(stderr, "xmlStreamPush() failure\n");
2033 xmlFreeStreamCtxt(patstream);
2034 patstream = NULL;
2035 }
2036 }
2037 }
Daniel Veillardd4301ab2005-02-03 22:24:10 +00002038#endif /* LIBXML_PATTERN_ENABLED */
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002039 reader = xmlReaderWalker(doc);
2040 if (reader != NULL) {
2041 if ((timing) && (!repeat)) {
2042 startTimer();
2043 }
2044 ret = xmlTextReaderRead(reader);
2045 while (ret == 1) {
Daniel Veillardb3de70c2003-12-02 22:32:15 +00002046 if ((debug)
2047#ifdef LIBXML_PATTERN_ENABLED
2048 || (patternc)
2049#endif
2050 )
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002051 processNode(reader);
2052 ret = xmlTextReaderRead(reader);
2053 }
2054 if ((timing) && (!repeat)) {
2055 endTimer("walking through the doc");
2056 }
2057 xmlFreeTextReader(reader);
2058 if (ret != 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002059 fprintf(stderr, "failed to walk through the doc\n");
William M. Brack8304d872004-06-08 13:29:32 +00002060 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002061 }
2062 } else {
2063 fprintf(stderr, "Failed to crate a reader from the document\n");
William M. Brack8304d872004-06-08 13:29:32 +00002064 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002065 }
Daniel Veillard2b2e02d2005-02-05 23:20:22 +00002066#ifdef LIBXML_PATTERN_ENABLED
2067 if (patstream != NULL) {
2068 xmlFreeStreamCtxt(patstream);
2069 patstream = NULL;
2070 }
2071#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002072}
Daniel Veillard81273902003-09-30 00:43:48 +00002073#endif /* LIBXML_READER_ENABLED */
Daniel Veillard7704fb12003-01-03 16:19:51 +00002074
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002075#ifdef LIBXML_XPATH_ENABLED
2076/************************************************************************
2077 * *
2078 * XPath Query *
2079 * *
2080 ************************************************************************/
2081
2082static void doXPathDump(xmlXPathObjectPtr cur) {
2083 switch(cur->type) {
2084 case XPATH_NODESET: {
2085 int i;
2086 xmlNodePtr node;
2087#ifdef LIBXML_OUTPUT_ENABLED
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002088 xmlOutputBufferPtr buf;
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002089
Daniel Veillardbdc64d62012-03-27 14:41:37 +08002090 if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr <= 0)) {
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002091 fprintf(stderr, "XPath set is empty\n");
2092 progresult = XMLLINT_ERR_XPATH;
2093 break;
2094 }
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002095 buf = xmlOutputBufferCreateFile(stdout, NULL);
2096 if (buf == NULL) {
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002097 fprintf(stderr, "Out of memory for XPath\n");
2098 progresult = XMLLINT_ERR_MEM;
2099 return;
2100 }
2101 for (i = 0;i < cur->nodesetval->nodeNr;i++) {
2102 node = cur->nodesetval->nodeTab[i];
Haibo Huangcfd91dc2020-07-30 23:01:33 -07002103 xmlNodeDumpOutput(buf, NULL, node, 0, 0, NULL);
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002104 xmlOutputBufferWrite(buf, 1, "\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002105 }
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002106 xmlOutputBufferClose(buf);
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002107#else
2108 printf("xpath returned %d nodes\n", cur->nodesetval->nodeNr);
2109#endif
2110 break;
2111 }
2112 case XPATH_BOOLEAN:
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002113 if (cur->boolval) printf("true\n");
2114 else printf("false\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002115 break;
2116 case XPATH_NUMBER:
2117 switch (xmlXPathIsInf(cur->floatval)) {
2118 case 1:
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002119 printf("Infinity\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002120 break;
2121 case -1:
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002122 printf("-Infinity\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002123 break;
2124 default:
2125 if (xmlXPathIsNaN(cur->floatval)) {
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002126 printf("NaN\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002127 } else {
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002128 printf("%0g\n", cur->floatval);
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002129 }
2130 }
2131 break;
2132 case XPATH_STRING:
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002133 printf("%s\n", (const char *) cur->stringval);
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002134 break;
2135 case XPATH_UNDEFINED:
2136 fprintf(stderr, "XPath Object is uninitialized\n");
2137 progresult = XMLLINT_ERR_XPATH;
2138 break;
2139 default:
2140 fprintf(stderr, "XPath object of unexpected type\n");
2141 progresult = XMLLINT_ERR_XPATH;
2142 break;
2143 }
2144}
2145
2146static void doXPathQuery(xmlDocPtr doc, const char *query) {
2147 xmlXPathContextPtr ctxt;
2148 xmlXPathObjectPtr res;
2149
2150 ctxt = xmlXPathNewContext(doc);
2151 if (ctxt == NULL) {
2152 fprintf(stderr, "Out of memory for XPath\n");
2153 progresult = XMLLINT_ERR_MEM;
2154 return;
2155 }
Daniel Veillard2e1eaca2012-05-25 16:44:20 +08002156 ctxt->node = (xmlNodePtr) doc;
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002157 res = xmlXPathEval(BAD_CAST query, ctxt);
2158 xmlXPathFreeContext(ctxt);
2159
2160 if (res == NULL) {
2161 fprintf(stderr, "XPath evaluation failure\n");
2162 progresult = XMLLINT_ERR_XPATH;
2163 return;
2164 }
2165 doXPathDump(res);
2166 xmlXPathFreeObject(res);
2167}
2168#endif /* LIBXML_XPATH_ENABLED */
2169
Daniel Veillard7704fb12003-01-03 16:19:51 +00002170/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +02002171 * *
2172 * Tree Test processing *
2173 * *
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002174 ************************************************************************/
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002175static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
Daniel Veillard652327a2003-09-29 18:02:38 +00002176 xmlDocPtr doc = NULL;
2177#ifdef LIBXML_TREE_ENABLED
2178 xmlDocPtr tmp;
2179#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002180
Daniel Veillard48b2f892001-02-25 16:11:03 +00002181 if ((timing) && (!repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00002182 startTimer();
Daniel Veillardf1edb102009-08-10 14:43:18 +02002183
Daniel Veillard48b2f892001-02-25 16:11:03 +00002184
Daniel Veillard652327a2003-09-29 18:02:38 +00002185#ifdef LIBXML_TREE_ENABLED
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002186 if (filename == NULL) {
2187 if (generate) {
2188 xmlNodePtr n;
2189
2190 doc = xmlNewDoc(BAD_CAST "1.0");
Daniel Veillard95ddcd32004-10-26 21:53:55 +00002191 n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002192 xmlNodeSetContent(n, BAD_CAST "abc");
2193 xmlDocSetRootElement(doc, n);
2194 }
2195 }
Daniel Veillard652327a2003-09-29 18:02:38 +00002196#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002197#ifdef LIBXML_HTML_ENABLED
Daniel Veillard73b013f2003-09-30 12:36:01 +00002198#ifdef LIBXML_PUSH_ENABLED
William M. Brack78637da2003-07-31 14:47:38 +00002199 else if ((html) && (push)) {
2200 FILE *f;
2201
Haibo Huangcfd91dc2020-07-30 23:01:33 -07002202 if ((filename[0] == '-') && (filename[1] == 0)) {
2203 f = stdin;
2204 } else {
William M. Brack3403add2004-06-27 02:07:51 +00002205#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
Haibo Huangcfd91dc2020-07-30 23:01:33 -07002206 f = fopen(filename, "rb");
Patrick Monnerat1c43f432013-12-12 15:12:53 +08002207#elif defined(__OS400__)
Haibo Huangcfd91dc2020-07-30 23:01:33 -07002208 f = fopen(filename, "rb");
William M. Brack3403add2004-06-27 02:07:51 +00002209#else
Haibo Huangcfd91dc2020-07-30 23:01:33 -07002210 f = fopen(filename, "r");
William M. Brack3403add2004-06-27 02:07:51 +00002211#endif
Haibo Huangcfd91dc2020-07-30 23:01:33 -07002212 }
William M. Brack78637da2003-07-31 14:47:38 +00002213 if (f != NULL) {
Daniel Veillard1abd2212012-10-25 15:37:50 +08002214 int res;
William M. Brack78637da2003-07-31 14:47:38 +00002215 char chars[4096];
2216 htmlParserCtxtPtr ctxt;
2217
William M. Brack78637da2003-07-31 14:47:38 +00002218 res = fread(chars, 1, 4, f);
2219 if (res > 0) {
2220 ctxt = htmlCreatePushParserCtxt(NULL, NULL,
William M. Brack1d75c8a2003-10-27 13:48:16 +00002221 chars, res, filename, XML_CHAR_ENCODING_NONE);
Elliott Hughesecdab2a2022-02-23 14:33:50 -08002222 if (ctxt == NULL) {
2223 progresult = XMLLINT_ERR_MEM;
2224 if (f != stdin)
2225 fclose(f);
2226 return;
2227 }
Elliott Hughes5cefca72021-05-06 13:23:15 -07002228 htmlCtxtUseOptions(ctxt, options);
Daniel Veillard1abd2212012-10-25 15:37:50 +08002229 while ((res = fread(chars, 1, pushsize, f)) > 0) {
William M. Brack78637da2003-07-31 14:47:38 +00002230 htmlParseChunk(ctxt, chars, res, 0);
2231 }
2232 htmlParseChunk(ctxt, chars, 0, 1);
2233 doc = ctxt->myDoc;
2234 htmlFreeParserCtxt(ctxt);
2235 }
Elliott Hughesecdab2a2022-02-23 14:33:50 -08002236 if (f != stdin)
2237 fclose(f);
William M. Brack78637da2003-07-31 14:47:38 +00002238 }
2239 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00002240#endif /* LIBXML_PUSH_ENABLED */
Daniel Richard G5706b6d2012-08-06 11:32:54 +08002241#ifdef HAVE_MMAP
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002242 else if ((html) && (memory)) {
2243 int fd;
2244 struct stat info;
2245 const char *base;
Daniel Veillardf1edb102009-08-10 14:43:18 +02002246 if (stat(filename, &info) < 0)
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002247 return;
2248 if ((fd = open(filename, O_RDONLY)) < 0)
2249 return;
2250 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillardb98c6a02013-07-12 12:08:40 +08002251 if (base == (void *) MAP_FAILED) {
2252 close(fd);
2253 fprintf(stderr, "mmap failure for file %s\n", filename);
2254 progresult = XMLLINT_ERR_RDFILE;
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002255 return;
Daniel Veillardb98c6a02013-07-12 12:08:40 +08002256 }
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002257
2258 doc = htmlReadMemory((char *) base, info.st_size, filename,
2259 NULL, options);
Daniel Veillardf1edb102009-08-10 14:43:18 +02002260
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002261 munmap((char *) base, info.st_size);
2262 close(fd);
2263 }
2264#endif
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002265 else if (html) {
Daniel Veillard9475a352003-09-26 12:47:50 +00002266 doc = htmlReadFile(filename, NULL, options);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002267 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002268#endif /* LIBXML_HTML_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002269 else {
Daniel Veillard73b013f2003-09-30 12:36:01 +00002270#ifdef LIBXML_PUSH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002271 /*
2272 * build an XML tree from a string;
2273 */
2274 if (push) {
2275 FILE *f;
2276
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002277 /* '-' Usually means stdin -<sven@zen.org> */
2278 if ((filename[0] == '-') && (filename[1] == 0)) {
2279 f = stdin;
2280 } else {
William M. Brack3403add2004-06-27 02:07:51 +00002281#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2282 f = fopen(filename, "rb");
Patrick Monnerat1c43f432013-12-12 15:12:53 +08002283#elif defined(__OS400__)
2284 f = fopen(filename, "rb");
William M. Brack3403add2004-06-27 02:07:51 +00002285#else
2286 f = fopen(filename, "r");
2287#endif
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002288 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002289 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +00002290 int ret;
Daniel Veillarda880b122003-04-21 21:36:41 +00002291 int res, size = 1024;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002292 char chars[1024];
2293 xmlParserCtxtPtr ctxt;
2294
Daniel Veillarda880b122003-04-21 21:36:41 +00002295 /* if (repeat) size = 1024; */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002296 res = fread(chars, 1, 4, f);
2297 if (res > 0) {
2298 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
2299 chars, res, filename);
Elliott Hughesecdab2a2022-02-23 14:33:50 -08002300 if (ctxt == NULL) {
2301 progresult = XMLLINT_ERR_MEM;
2302 if (f != stdin)
2303 fclose(f);
2304 return;
2305 }
Daniel Veillard500a1de2004-03-22 15:22:58 +00002306 xmlCtxtUseOptions(ctxt, options);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002307 while ((res = fread(chars, 1, size, f)) > 0) {
2308 xmlParseChunk(ctxt, chars, res, 0);
2309 }
2310 xmlParseChunk(ctxt, chars, 0, 1);
2311 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +00002312 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002313 xmlFreeParserCtxt(ctxt);
Haibo Huangf0a546b2020-09-01 20:28:19 -07002314 if ((!ret) && (!recovery)) {
Daniel Veillarde715dd22000-08-29 18:29:38 +00002315 xmlFreeDoc(doc);
2316 doc = NULL;
2317 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002318 }
Daniel Veillard84bff682009-09-11 15:30:19 +02002319 if (f != stdin)
2320 fclose(f);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002321 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00002322 } else
2323#endif /* LIBXML_PUSH_ENABLED */
2324 if (testIO) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002325 if ((filename[0] == '-') && (filename[1] == 0)) {
Daniel Veillard60942de2003-09-25 21:05:58 +00002326 doc = xmlReadFd(0, NULL, NULL, options);
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002327 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002328 FILE *f;
Daniel Veillard5e873c42000-04-12 13:27:38 +00002329
William M. Brack3403add2004-06-27 02:07:51 +00002330#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2331 f = fopen(filename, "rb");
Patrick Monnerat1c43f432013-12-12 15:12:53 +08002332#elif defined(__OS400__)
2333 f = fopen(filename, "rb");
William M. Brack3403add2004-06-27 02:07:51 +00002334#else
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002335 f = fopen(filename, "r");
William M. Brack3403add2004-06-27 02:07:51 +00002336#endif
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002337 if (f != NULL) {
2338 if (rectxt == NULL)
Nick Wellnhofer86615e42017-11-09 17:47:47 +01002339 doc = xmlReadIO(myRead, myClose, f, filename, NULL,
2340 options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002341 else
Nick Wellnhofer86615e42017-11-09 17:47:47 +01002342 doc = xmlCtxtReadIO(rectxt, myRead, myClose, f,
2343 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002344 } else
Daniel Veillard5e873c42000-04-12 13:27:38 +00002345 doc = NULL;
Daniel Veillard5e873c42000-04-12 13:27:38 +00002346 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002347 } else if (htmlout) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002348 xmlParserCtxtPtr ctxt;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002349
Elliott Hughesecdab2a2022-02-23 14:33:50 -08002350 if (rectxt == NULL) {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002351 ctxt = xmlNewParserCtxt();
Elliott Hughesecdab2a2022-02-23 14:33:50 -08002352 if (ctxt == NULL) {
2353 progresult = XMLLINT_ERR_MEM;
2354 return;
2355 }
2356 } else {
2357 ctxt = rectxt;
2358 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002359
Elliott Hughesecdab2a2022-02-23 14:33:50 -08002360 ctxt->sax->error = xmlHTMLError;
2361 ctxt->sax->warning = xmlHTMLWarning;
2362 ctxt->vctxt.error = xmlHTMLValidityError;
2363 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002364
Elliott Hughesecdab2a2022-02-23 14:33:50 -08002365 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
2366
2367 if (rectxt == NULL)
2368 xmlFreeParserCtxt(ctxt);
Daniel Richard G5706b6d2012-08-06 11:32:54 +08002369#ifdef HAVE_MMAP
Daniel Veillard46e370e2000-07-21 20:32:03 +00002370 } else if (memory) {
2371 int fd;
2372 struct stat info;
2373 const char *base;
Daniel Veillardf1edb102009-08-10 14:43:18 +02002374 if (stat(filename, &info) < 0)
Daniel Veillard46e370e2000-07-21 20:32:03 +00002375 return;
2376 if ((fd = open(filename, O_RDONLY)) < 0)
2377 return;
2378 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillarda75a0092013-05-08 13:45:48 +08002379 if (base == (void *) MAP_FAILED) {
Daniel Veillardb98c6a02013-07-12 12:08:40 +08002380 close(fd);
Daniel Veillarda75a0092013-05-08 13:45:48 +08002381 fprintf(stderr, "mmap failure for file %s\n", filename);
2382 progresult = XMLLINT_ERR_RDFILE;
Daniel Veillard46e370e2000-07-21 20:32:03 +00002383 return;
Daniel Veillarda75a0092013-05-08 13:45:48 +08002384 }
Daniel Veillard46e370e2000-07-21 20:32:03 +00002385
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002386 if (rectxt == NULL)
Daniel Veillard60942de2003-09-25 21:05:58 +00002387 doc = xmlReadMemory((char *) base, info.st_size,
2388 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002389 else
Daniel Veillard60942de2003-09-25 21:05:58 +00002390 doc = xmlCtxtReadMemory(rectxt, (char *) base, info.st_size,
2391 filename, NULL, options);
Daniel Veillardf1edb102009-08-10 14:43:18 +02002392
Daniel Veillard46e370e2000-07-21 20:32:03 +00002393 munmap((char *) base, info.st_size);
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002394 close(fd);
Daniel Veillard46e370e2000-07-21 20:32:03 +00002395#endif
Daniel Veillard4432df22003-09-28 18:58:27 +00002396#ifdef LIBXML_VALID_ENABLED
Daniel Veillardea7751d2002-12-20 00:16:24 +00002397 } else if (valid) {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002398 xmlParserCtxtPtr ctxt = NULL;
Daniel Veillardea7751d2002-12-20 00:16:24 +00002399
Elliott Hughesecdab2a2022-02-23 14:33:50 -08002400 if (rectxt == NULL) {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002401 ctxt = xmlNewParserCtxt();
Elliott Hughesecdab2a2022-02-23 14:33:50 -08002402 if (ctxt == NULL) {
2403 progresult = XMLLINT_ERR_MEM;
2404 return;
2405 }
2406 } else {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002407 ctxt = rectxt;
Elliott Hughesecdab2a2022-02-23 14:33:50 -08002408 }
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002409
Elliott Hughesecdab2a2022-02-23 14:33:50 -08002410 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
2411
2412 if (ctxt->valid == 0)
2413 progresult = XMLLINT_ERR_RDFILE;
2414 if (rectxt == NULL)
2415 xmlFreeParserCtxt(ctxt);
Daniel Veillard4432df22003-09-28 18:58:27 +00002416#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardea7751d2002-12-20 00:16:24 +00002417 } else {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002418 if (rectxt != NULL)
2419 doc = xmlCtxtReadFile(rectxt, filename, NULL, options);
Daniel Veillard81562d22005-06-15 13:27:56 +00002420 else {
2421#ifdef LIBXML_SAX1_ENABLED
2422 if (sax1)
2423 doc = xmlParseFile(filename);
2424 else
2425#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002426 doc = xmlReadFile(filename, NULL, options);
Daniel Veillard81562d22005-06-15 13:27:56 +00002427 }
Daniel Veillardea7751d2002-12-20 00:16:24 +00002428 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002429 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002430
Daniel Veillard88a172f2000-08-04 18:23:10 +00002431 /*
2432 * If we don't have a document we might as well give up. Do we
2433 * want an error message here? <sven@zen.org> */
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002434 if (doc == NULL) {
William M. Brack8304d872004-06-08 13:29:32 +00002435 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard88a172f2000-08-04 18:23:10 +00002436 return;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002437 }
2438
Daniel Veillard48b2f892001-02-25 16:11:03 +00002439 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002440 endTimer("Parsing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002441 }
2442
Daniel Veillard29e43992001-12-13 22:21:58 +00002443 /*
2444 * Remove DOCTYPE nodes
2445 */
2446 if (dropdtd) {
2447 xmlDtdPtr dtd;
2448
2449 dtd = xmlGetIntSubset(doc);
2450 if (dtd != NULL) {
2451 xmlUnlinkNode((xmlNodePtr)dtd);
Elliott Hughes5cefca72021-05-06 13:23:15 -07002452 doc->intSubset = NULL;
Daniel Veillard29e43992001-12-13 22:21:58 +00002453 xmlFreeDtd(dtd);
2454 }
2455 }
2456
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002457#ifdef LIBXML_XINCLUDE_ENABLED
Daniel Veillard48b2f892001-02-25 16:11:03 +00002458 if (xinclude) {
2459 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002460 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002461 }
William M. Brack4e1c2db2005-02-11 10:58:55 +00002462 if (xmlXIncludeProcessFlags(doc, options) < 0)
2463 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard48b2f892001-02-25 16:11:03 +00002464 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002465 endTimer("Xinclude processing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002466 }
2467 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002468#endif
Daniel Veillard88a172f2000-08-04 18:23:10 +00002469
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002470#ifdef LIBXML_XPATH_ENABLED
2471 if (xpathquery != NULL) {
2472 doXPathQuery(doc, xpathquery);
2473 }
2474#endif
2475
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002476#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00002477#ifdef LIBXML_XPATH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002478 /*
Daniel Veillardcbaf3992001-12-31 16:16:02 +00002479 * shell interaction
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002480 */
Daniel Veillard26a45c82006-10-20 12:55:34 +00002481 if (shell) {
2482 xmlXPathOrderDocElems(doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002483 xmlShell(doc, filename, xmlShellReadline, stdout);
Daniel Veillard26a45c82006-10-20 12:55:34 +00002484 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002485#endif
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00002486#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002487
Daniel Veillard652327a2003-09-29 18:02:38 +00002488#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002489 /*
2490 * test intermediate copy if needed.
2491 */
2492 if (copy) {
2493 tmp = doc;
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002494 if (timing) {
2495 startTimer();
2496 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002497 doc = xmlCopyDoc(doc, 1);
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002498 if (timing) {
2499 endTimer("Copying");
2500 }
2501 if (timing) {
2502 startTimer();
2503 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002504 xmlFreeDoc(tmp);
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002505 if (timing) {
2506 endTimer("Freeing original");
2507 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002508 }
Daniel Veillard652327a2003-09-29 18:02:38 +00002509#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002510
Daniel Veillard4432df22003-09-28 18:58:27 +00002511#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002512 if ((insert) && (!html)) {
2513 const xmlChar* list[256];
2514 int nb, i;
2515 xmlNodePtr node;
2516
2517 if (doc->children != NULL) {
2518 node = doc->children;
2519 while ((node != NULL) && (node->last == NULL)) node = node->next;
2520 if (node != NULL) {
2521 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
2522 if (nb < 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002523 fprintf(stderr, "could not get valid list of elements\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002524 } else if (nb == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002525 fprintf(stderr, "No element can be inserted under root\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002526 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002527 fprintf(stderr, "%d element types can be inserted under root:\n",
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002528 nb);
2529 for (i = 0;i < nb;i++) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002530 fprintf(stderr, "%s\n", (char *) list[i]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002531 }
2532 }
2533 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02002534 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002535 }else
2536#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002537#ifdef LIBXML_READER_ENABLED
2538 if (walker) {
2539 walkDoc(doc);
2540 }
2541#endif /* LIBXML_READER_ENABLED */
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002542#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard4432df22003-09-28 18:58:27 +00002543 if (noout == 0) {
Daniel Veillard3df01182003-12-10 10:17:51 +00002544 int ret;
2545
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002546 /*
2547 * print it.
2548 */
2549#ifdef LIBXML_DEBUG_ENABLED
2550 if (!debug) {
2551#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00002552 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002553 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002554 }
Daniel Veillard656ce942004-04-30 23:11:45 +00002555#ifdef LIBXML_HTML_ENABLED
Daniel Veillard42fd4122003-11-04 08:47:48 +00002556 if ((html) && (!xmlout)) {
2557 if (compress) {
2558 htmlSaveFile(output ? output : "-", doc);
2559 }
2560 else if (encoding != NULL) {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002561 if (format == 1) {
Daniel Veillard42fd4122003-11-04 08:47:48 +00002562 htmlSaveFileFormat(output ? output : "-", doc, encoding, 1);
2563 }
2564 else {
2565 htmlSaveFileFormat(output ? output : "-", doc, encoding, 0);
2566 }
2567 }
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002568 else if (format == 1) {
Daniel Veillard42fd4122003-11-04 08:47:48 +00002569 htmlSaveFileFormat(output ? output : "-", doc, NULL, 1);
2570 }
2571 else {
2572 FILE *out;
2573 if (output == NULL)
2574 out = stdout;
2575 else {
2576 out = fopen(output,"wb");
2577 }
2578 if (out != NULL) {
2579 if (htmlDocDump(out, doc) < 0)
William M. Brack8304d872004-06-08 13:29:32 +00002580 progresult = XMLLINT_ERR_OUT;
Daniel Veillard42fd4122003-11-04 08:47:48 +00002581
2582 if (output != NULL)
2583 fclose(out);
2584 } else {
2585 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00002586 progresult = XMLLINT_ERR_OUT;
Daniel Veillard42fd4122003-11-04 08:47:48 +00002587 }
2588 }
2589 if ((timing) && (!repeat)) {
2590 endTimer("Saving");
2591 }
2592 } else
2593#endif
Daniel Veillard25048d82004-08-14 22:37:54 +00002594#ifdef LIBXML_C14N_ENABLED
2595 if (canonical) {
2596 xmlChar *result = NULL;
2597 int size;
2598
Aleksey Sanin83868242009-07-09 10:26:22 +02002599 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_0, NULL, 1, &result);
2600 if (size >= 0) {
Stefan Kostdff8d0f2011-05-09 12:14:59 +03002601 if (write(1, result, size) == -1) {
2602 fprintf(stderr, "Can't write data\n");
2603 }
Aleksey Sanin83868242009-07-09 10:26:22 +02002604 xmlFree(result);
2605 } else {
2606 fprintf(stderr, "Failed to canonicalize\n");
2607 progresult = XMLLINT_ERR_OUT;
2608 }
Sérgio Batistad9ea9132014-06-09 22:10:15 +08002609 } else if (canonical_11) {
Aleksey Sanin83868242009-07-09 10:26:22 +02002610 xmlChar *result = NULL;
2611 int size;
2612
2613 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_1, NULL, 1, &result);
Daniel Veillard25048d82004-08-14 22:37:54 +00002614 if (size >= 0) {
Stefan Kostdff8d0f2011-05-09 12:14:59 +03002615 if (write(1, result, size) == -1) {
2616 fprintf(stderr, "Can't write data\n");
2617 }
Daniel Veillard25048d82004-08-14 22:37:54 +00002618 xmlFree(result);
2619 } else {
2620 fprintf(stderr, "Failed to canonicalize\n");
2621 progresult = XMLLINT_ERR_OUT;
2622 }
2623 } else
Aleksey Sanin2650df12005-06-06 17:16:50 +00002624 if (exc_canonical) {
2625 xmlChar *result = NULL;
2626 int size;
2627
Aleksey Sanin83868242009-07-09 10:26:22 +02002628 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_EXCLUSIVE_1_0, NULL, 1, &result);
Aleksey Sanin2650df12005-06-06 17:16:50 +00002629 if (size >= 0) {
Stefan Kostdff8d0f2011-05-09 12:14:59 +03002630 if (write(1, result, size) == -1) {
2631 fprintf(stderr, "Can't write data\n");
2632 }
Aleksey Sanin2650df12005-06-06 17:16:50 +00002633 xmlFree(result);
2634 } else {
2635 fprintf(stderr, "Failed to canonicalize\n");
2636 progresult = XMLLINT_ERR_OUT;
2637 }
2638 } else
Daniel Veillard25048d82004-08-14 22:37:54 +00002639#endif
Daniel Richard G5706b6d2012-08-06 11:32:54 +08002640#ifdef HAVE_MMAP
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002641 if (memory) {
2642 xmlChar *result;
2643 int len;
2644
2645 if (encoding != NULL) {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002646 if (format == 1) {
Daniel Veillardd536f702001-11-08 17:32:47 +00002647 xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
Daniel Veillardf1edb102009-08-10 14:43:18 +02002648 } else {
Daniel Veillardd536f702001-11-08 17:32:47 +00002649 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
2650 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002651 } else {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002652 if (format == 1)
Daniel Veillard90493a92001-08-14 14:12:47 +00002653 xmlDocDumpFormatMemory(doc, &result, &len, 1);
2654 else
2655 xmlDocDumpMemory(doc, &result, &len);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002656 }
2657 if (result == NULL) {
2658 fprintf(stderr, "Failed to save\n");
Daniel Veillard25048d82004-08-14 22:37:54 +00002659 progresult = XMLLINT_ERR_OUT;
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002660 } else {
Stefan Kostdff8d0f2011-05-09 12:14:59 +03002661 if (write(1, result, len) == -1) {
2662 fprintf(stderr, "Can't write data\n");
2663 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002664 xmlFree(result);
2665 }
Daniel Veillarddab39b52006-10-16 23:22:10 +00002666
Daniel Veillard3b2c2612001-04-04 00:09:00 +00002667 } else
Daniel Richard G5706b6d2012-08-06 11:32:54 +08002668#endif /* HAVE_MMAP */
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002669 if (compress) {
2670 xmlSaveFile(output ? output : "-", doc);
Daniel Veillarddab39b52006-10-16 23:22:10 +00002671 } else if (oldout) {
2672 if (encoding != NULL) {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002673 if (format == 1) {
Daniel Veillarddab39b52006-10-16 23:22:10 +00002674 ret = xmlSaveFormatFileEnc(output ? output : "-", doc,
2675 encoding, 1);
2676 }
2677 else {
2678 ret = xmlSaveFileEnc(output ? output : "-", doc,
2679 encoding);
2680 }
2681 if (ret < 0) {
2682 fprintf(stderr, "failed save to %s\n",
2683 output ? output : "-");
2684 progresult = XMLLINT_ERR_OUT;
2685 }
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002686 } else if (format == 1) {
Daniel Veillarddab39b52006-10-16 23:22:10 +00002687 ret = xmlSaveFormatFile(output ? output : "-", doc, 1);
2688 if (ret < 0) {
2689 fprintf(stderr, "failed save to %s\n",
2690 output ? output : "-");
2691 progresult = XMLLINT_ERR_OUT;
2692 }
Daniel Veillard05d987b2003-10-08 11:54:57 +00002693 } else {
Daniel Veillarddab39b52006-10-16 23:22:10 +00002694 FILE *out;
2695 if (output == NULL)
2696 out = stdout;
2697 else {
2698 out = fopen(output,"wb");
2699 }
2700 if (out != NULL) {
2701 if (xmlDocDump(out, doc) < 0)
2702 progresult = XMLLINT_ERR_OUT;
2703
2704 if (output != NULL)
2705 fclose(out);
2706 } else {
2707 fprintf(stderr, "failed to open %s\n", output);
2708 progresult = XMLLINT_ERR_OUT;
2709 }
2710 }
2711 } else {
2712 xmlSaveCtxtPtr ctxt;
2713 int saveOpts = 0;
2714
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002715 if (format == 1)
Daniel Veillarddab39b52006-10-16 23:22:10 +00002716 saveOpts |= XML_SAVE_FORMAT;
Adam Spraggd2e62312010-11-03 15:33:40 +01002717 else if (format == 2)
2718 saveOpts |= XML_SAVE_WSNONSIG;
Daniel Veillard9ccea572010-03-10 15:02:49 +01002719
2720#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
Daniel Veillard9d962642009-08-23 15:31:18 +02002721 if (xmlout)
2722 saveOpts |= XML_SAVE_AS_XML;
Daniel Veillard9ccea572010-03-10 15:02:49 +01002723#endif
Daniel Veillarddab39b52006-10-16 23:22:10 +00002724
2725 if (output == NULL)
2726 ctxt = xmlSaveToFd(1, encoding, saveOpts);
2727 else
2728 ctxt = xmlSaveToFilename(output, encoding, saveOpts);
2729
2730 if (ctxt != NULL) {
2731 if (xmlSaveDoc(ctxt, doc) < 0) {
2732 fprintf(stderr, "failed save to %s\n",
2733 output ? output : "-");
2734 progresult = XMLLINT_ERR_OUT;
2735 }
2736 xmlSaveClose(ctxt);
2737 } else {
William M. Brack8304d872004-06-08 13:29:32 +00002738 progresult = XMLLINT_ERR_OUT;
Daniel Veillard05d987b2003-10-08 11:54:57 +00002739 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002740 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002741 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002742 endTimer("Saving");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002743 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002744#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002745 } else {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002746 FILE *out;
2747 if (output == NULL)
2748 out = stdout;
2749 else {
2750 out = fopen(output,"wb");
2751 }
Daniel Veillard05d987b2003-10-08 11:54:57 +00002752 if (out != NULL) {
2753 xmlDebugDumpDocument(out, doc);
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002754
Daniel Veillard05d987b2003-10-08 11:54:57 +00002755 if (output != NULL)
2756 fclose(out);
2757 } else {
2758 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00002759 progresult = XMLLINT_ERR_OUT;
Daniel Veillard05d987b2003-10-08 11:54:57 +00002760 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002761 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002762#endif
2763 }
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002764#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002765
Daniel Veillard4432df22003-09-28 18:58:27 +00002766#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002767 /*
2768 * A posteriori validation test
2769 */
Daniel Veillard66f68e72003-08-18 16:39:51 +00002770 if ((dtdvalid != NULL) || (dtdvalidfpi != NULL)) {
Daniel Veillardcd429612000-10-11 15:57:05 +00002771 xmlDtdPtr dtd;
2772
Daniel Veillard48b2f892001-02-25 16:11:03 +00002773 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002774 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002775 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00002776 if (dtdvalid != NULL)
Daniel Veillardf1edb102009-08-10 14:43:18 +02002777 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
Daniel Veillard66f68e72003-08-18 16:39:51 +00002778 else
Daniel Veillardf1edb102009-08-10 14:43:18 +02002779 dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL);
Daniel Veillard48b2f892001-02-25 16:11:03 +00002780 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002781 endTimer("Parsing DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002782 }
Daniel Veillardcd429612000-10-11 15:57:05 +00002783 if (dtd == NULL) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00002784 if (dtdvalid != NULL)
2785 xmlGenericError(xmlGenericErrorContext,
2786 "Could not parse DTD %s\n", dtdvalid);
2787 else
2788 xmlGenericError(xmlGenericErrorContext,
2789 "Could not parse DTD %s\n", dtdvalidfpi);
William M. Brack8304d872004-06-08 13:29:32 +00002790 progresult = XMLLINT_ERR_DTD;
Daniel Veillardcd429612000-10-11 15:57:05 +00002791 } else {
Daniel Veillarda37aab82003-06-09 09:10:36 +00002792 xmlValidCtxtPtr cvp;
2793
2794 if ((cvp = xmlNewValidCtxt()) == NULL) {
2795 xmlGenericError(xmlGenericErrorContext,
2796 "Couldn't allocate validation context\n");
Elliott Hughesecdab2a2022-02-23 14:33:50 -08002797 progresult = XMLLINT_ERR_MEM;
2798 xmlFreeDtd(dtd);
2799 return;
Daniel Veillarda37aab82003-06-09 09:10:36 +00002800 }
Haibo Huangcfd91dc2020-07-30 23:01:33 -07002801 cvp->userData = NULL;
2802 cvp->error = xmlGenericError;
2803 cvp->warning = xmlGenericError;
Daniel Veillarda37aab82003-06-09 09:10:36 +00002804
Daniel Veillard48b2f892001-02-25 16:11:03 +00002805 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002806 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002807 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002808 if (!xmlValidateDtd(cvp, doc, dtd)) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00002809 if (dtdvalid != NULL)
2810 xmlGenericError(xmlGenericErrorContext,
2811 "Document %s does not validate against %s\n",
2812 filename, dtdvalid);
2813 else
2814 xmlGenericError(xmlGenericErrorContext,
2815 "Document %s does not validate against %s\n",
2816 filename, dtdvalidfpi);
William M. Brack8304d872004-06-08 13:29:32 +00002817 progresult = XMLLINT_ERR_VALID;
Daniel Veillardcd429612000-10-11 15:57:05 +00002818 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002819 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002820 endTimer("Validating against DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002821 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002822 xmlFreeValidCtxt(cvp);
Daniel Veillardcd429612000-10-11 15:57:05 +00002823 xmlFreeDtd(dtd);
2824 }
2825 } else if (postvalid) {
Daniel Veillarda37aab82003-06-09 09:10:36 +00002826 xmlValidCtxtPtr cvp;
2827
2828 if ((cvp = xmlNewValidCtxt()) == NULL) {
2829 xmlGenericError(xmlGenericErrorContext,
2830 "Couldn't allocate validation context\n");
Elliott Hughesecdab2a2022-02-23 14:33:50 -08002831 progresult = XMLLINT_ERR_MEM;
2832 xmlFreeDoc(doc);
2833 return;
Daniel Veillarda37aab82003-06-09 09:10:36 +00002834 }
2835
Daniel Veillard48b2f892001-02-25 16:11:03 +00002836 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002837 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002838 }
Haibo Huangcfd91dc2020-07-30 23:01:33 -07002839 cvp->userData = NULL;
2840 cvp->error = xmlGenericError;
2841 cvp->warning = xmlGenericError;
Daniel Veillarda37aab82003-06-09 09:10:36 +00002842 if (!xmlValidateDocument(cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00002843 xmlGenericError(xmlGenericErrorContext,
2844 "Document %s does not validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002845 progresult = XMLLINT_ERR_VALID;
Daniel Veillardcd429612000-10-11 15:57:05 +00002846 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002847 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002848 endTimer("Validating");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002849 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002850 xmlFreeValidCtxt(cvp);
Daniel Veillard4432df22003-09-28 18:58:27 +00002851 }
2852#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardd4501d72005-07-24 14:27:16 +00002853#ifdef LIBXML_SCHEMATRON_ENABLED
2854 if (wxschematron != NULL) {
2855 xmlSchematronValidCtxtPtr ctxt;
2856 int ret;
Daniel Veillardc740a172005-07-31 12:17:24 +00002857 int flag;
Daniel Veillardd4501d72005-07-24 14:27:16 +00002858
2859 if ((timing) && (!repeat)) {
2860 startTimer();
2861 }
2862
2863 if (debug)
2864 flag = XML_SCHEMATRON_OUT_XML;
Daniel Veillardc740a172005-07-31 12:17:24 +00002865 else
2866 flag = XML_SCHEMATRON_OUT_TEXT;
2867 if (noout)
2868 flag |= XML_SCHEMATRON_OUT_QUIET;
Daniel Veillardd4501d72005-07-24 14:27:16 +00002869 ctxt = xmlSchematronNewValidCtxt(wxschematron, flag);
Elliott Hughesecdab2a2022-02-23 14:33:50 -08002870 if (ctxt == NULL) {
2871 progresult = XMLLINT_ERR_MEM;
2872 xmlFreeDoc(doc);
2873 return;
2874 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00002875#if 0
Haibo Huangcfd91dc2020-07-30 23:01:33 -07002876 xmlSchematronSetValidErrors(ctxt, xmlGenericError, xmlGenericError,
2877 NULL);
Daniel Veillardd4501d72005-07-24 14:27:16 +00002878#endif
2879 ret = xmlSchematronValidateDoc(ctxt, doc);
2880 if (ret == 0) {
Haibo Huang735158e2021-02-23 17:48:08 -08002881 if (!quiet) {
2882 fprintf(stderr, "%s validates\n", filename);
2883 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00002884 } else if (ret > 0) {
2885 fprintf(stderr, "%s fails to validate\n", filename);
2886 progresult = XMLLINT_ERR_VALID;
2887 } else {
2888 fprintf(stderr, "%s validation generated an internal error\n",
2889 filename);
2890 progresult = XMLLINT_ERR_VALID;
2891 }
2892 xmlSchematronFreeValidCtxt(ctxt);
2893 if ((timing) && (!repeat)) {
2894 endTimer("Validating");
2895 }
2896 }
2897#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00002898#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard4432df22003-09-28 18:58:27 +00002899 if (relaxngschemas != NULL) {
Daniel Veillard71531f32003-02-05 13:19:53 +00002900 xmlRelaxNGValidCtxtPtr ctxt;
2901 int ret;
2902
Daniel Veillard42f12e92003-03-07 18:32:59 +00002903 if ((timing) && (!repeat)) {
2904 startTimer();
2905 }
2906
Daniel Veillard71531f32003-02-05 13:19:53 +00002907 ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
Elliott Hughesecdab2a2022-02-23 14:33:50 -08002908 if (ctxt == NULL) {
2909 progresult = XMLLINT_ERR_MEM;
2910 xmlFreeDoc(doc);
2911 return;
2912 }
Haibo Huangcfd91dc2020-07-30 23:01:33 -07002913 xmlRelaxNGSetValidErrors(ctxt, xmlGenericError, xmlGenericError, NULL);
Daniel Veillard71531f32003-02-05 13:19:53 +00002914 ret = xmlRelaxNGValidateDoc(ctxt, doc);
2915 if (ret == 0) {
Haibo Huang735158e2021-02-23 17:48:08 -08002916 if (!quiet) {
2917 fprintf(stderr, "%s validates\n", filename);
2918 }
Daniel Veillard71531f32003-02-05 13:19:53 +00002919 } else if (ret > 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002920 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002921 progresult = XMLLINT_ERR_VALID;
Daniel Veillard71531f32003-02-05 13:19:53 +00002922 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002923 fprintf(stderr, "%s validation generated an internal error\n",
Daniel Veillard71531f32003-02-05 13:19:53 +00002924 filename);
William M. Brack8304d872004-06-08 13:29:32 +00002925 progresult = XMLLINT_ERR_VALID;
Daniel Veillard71531f32003-02-05 13:19:53 +00002926 }
2927 xmlRelaxNGFreeValidCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00002928 if ((timing) && (!repeat)) {
2929 endTimer("Validating");
2930 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002931 } else if (wxschemas != NULL) {
2932 xmlSchemaValidCtxtPtr ctxt;
2933 int ret;
2934
2935 if ((timing) && (!repeat)) {
2936 startTimer();
2937 }
2938
2939 ctxt = xmlSchemaNewValidCtxt(wxschemas);
Elliott Hughesecdab2a2022-02-23 14:33:50 -08002940 if (ctxt == NULL) {
2941 progresult = XMLLINT_ERR_MEM;
2942 xmlFreeDoc(doc);
2943 return;
2944 }
Haibo Huangcfd91dc2020-07-30 23:01:33 -07002945 xmlSchemaSetValidErrors(ctxt, xmlGenericError, xmlGenericError, NULL);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002946 ret = xmlSchemaValidateDoc(ctxt, doc);
2947 if (ret == 0) {
Haibo Huang735158e2021-02-23 17:48:08 -08002948 if (!quiet) {
2949 fprintf(stderr, "%s validates\n", filename);
2950 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002951 } else if (ret > 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002952 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002953 progresult = XMLLINT_ERR_VALID;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002954 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002955 fprintf(stderr, "%s validation generated an internal error\n",
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002956 filename);
William M. Brack8304d872004-06-08 13:29:32 +00002957 progresult = XMLLINT_ERR_VALID;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002958 }
2959 xmlSchemaFreeValidCtxt(ctxt);
2960 if ((timing) && (!repeat)) {
2961 endTimer("Validating");
2962 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002963 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002964#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002965
2966#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillard6b099012008-11-06 13:47:39 +00002967#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002968 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00002969 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002970#endif
Daniel Veillard6b099012008-11-06 13:47:39 +00002971#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002972
2973 /*
2974 * free it.
2975 */
Daniel Veillard48b2f892001-02-25 16:11:03 +00002976 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002977 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002978 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002979 xmlFreeDoc(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +00002980 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002981 endTimer("Freeing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002982 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002983}
2984
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002985/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +02002986 * *
2987 * Usage and Main *
2988 * *
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002989 ************************************************************************/
2990
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002991static void showVersion(const char *name) {
2992 fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
2993 fprintf(stderr, " compiled with: ");
Daniel Veillard602434d2005-09-12 09:20:31 +00002994 if (xmlHasFeature(XML_WITH_THREAD)) fprintf(stderr, "Threads ");
2995 if (xmlHasFeature(XML_WITH_TREE)) fprintf(stderr, "Tree ");
2996 if (xmlHasFeature(XML_WITH_OUTPUT)) fprintf(stderr, "Output ");
2997 if (xmlHasFeature(XML_WITH_PUSH)) fprintf(stderr, "Push ");
2998 if (xmlHasFeature(XML_WITH_READER)) fprintf(stderr, "Reader ");
2999 if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(stderr, "Patterns ");
3000 if (xmlHasFeature(XML_WITH_WRITER)) fprintf(stderr, "Writer ");
3001 if (xmlHasFeature(XML_WITH_SAX1)) fprintf(stderr, "SAXv1 ");
Daniel Veillardf1edb102009-08-10 14:43:18 +02003002 if (xmlHasFeature(XML_WITH_FTP)) fprintf(stderr, "FTP ");
3003 if (xmlHasFeature(XML_WITH_HTTP)) fprintf(stderr, "HTTP ");
Daniel Veillard602434d2005-09-12 09:20:31 +00003004 if (xmlHasFeature(XML_WITH_VALID)) fprintf(stderr, "DTDValid ");
Daniel Veillardf1edb102009-08-10 14:43:18 +02003005 if (xmlHasFeature(XML_WITH_HTML)) fprintf(stderr, "HTML ");
3006 if (xmlHasFeature(XML_WITH_LEGACY)) fprintf(stderr, "Legacy ");
3007 if (xmlHasFeature(XML_WITH_C14N)) fprintf(stderr, "C14N ");
3008 if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(stderr, "Catalog ");
3009 if (xmlHasFeature(XML_WITH_XPATH)) fprintf(stderr, "XPath ");
3010 if (xmlHasFeature(XML_WITH_XPTR)) fprintf(stderr, "XPointer ");
3011 if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(stderr, "XInclude ");
3012 if (xmlHasFeature(XML_WITH_ICONV)) fprintf(stderr, "Iconv ");
David Kilzer783931f2016-03-02 12:48:51 -08003013 if (xmlHasFeature(XML_WITH_ICU)) fprintf(stderr, "ICU ");
Daniel Veillardf1edb102009-08-10 14:43:18 +02003014 if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(stderr, "ISO8859X ");
3015 if (xmlHasFeature(XML_WITH_UNICODE)) fprintf(stderr, "Unicode ");
3016 if (xmlHasFeature(XML_WITH_REGEXP)) fprintf(stderr, "Regexps ");
3017 if (xmlHasFeature(XML_WITH_AUTOMATA)) fprintf(stderr, "Automata ");
3018 if (xmlHasFeature(XML_WITH_EXPR)) fprintf(stderr, "Expr ");
3019 if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(stderr, "Schemas ");
3020 if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(stderr, "Schematron ");
3021 if (xmlHasFeature(XML_WITH_MODULES)) fprintf(stderr, "Modules ");
3022 if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(stderr, "Debug ");
3023 if (xmlHasFeature(XML_WITH_DEBUG_MEM)) fprintf(stderr, "MemDebug ");
3024 if (xmlHasFeature(XML_WITH_DEBUG_RUN)) fprintf(stderr, "RunDebug ");
Daniel Veillard75acfee2006-07-13 06:29:56 +00003025 if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(stderr, "Zlib ");
Anders F Bjorklundeae52612011-09-18 16:59:13 +02003026 if (xmlHasFeature(XML_WITH_LZMA)) fprintf(stderr, "Lzma ");
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00003027 fprintf(stderr, "\n");
3028}
3029
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003030static void usage(FILE *f, const char *name) {
3031 fprintf(f, "Usage : %s [options] XMLfiles ...\n", name);
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003032#ifdef LIBXML_OUTPUT_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003033 fprintf(f, "\tParse the XML files and output the result of the parsing\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003034#else
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003035 fprintf(f, "\tParse the XML files\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003036#endif /* LIBXML_OUTPUT_ENABLED */
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003037 fprintf(f, "\t--version : display the version of the XML library used\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003038#ifdef LIBXML_DEBUG_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003039 fprintf(f, "\t--debug : dump a debug tree of the in-memory document\n");
3040 fprintf(f, "\t--shell : run a navigating shell\n");
3041 fprintf(f, "\t--debugent : debug the entities defined in the document\n");
Daniel Veillard8326e732003-01-07 00:19:07 +00003042#else
Daniel Veillard81273902003-09-30 00:43:48 +00003043#ifdef LIBXML_READER_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003044 fprintf(f, "\t--debug : dump the nodes content when using --stream\n");
Daniel Veillard81273902003-09-30 00:43:48 +00003045#endif /* LIBXML_READER_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003046#endif
Daniel Veillard652327a2003-09-29 18:02:38 +00003047#ifdef LIBXML_TREE_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003048 fprintf(f, "\t--copy : used to test the internal copy implementation\n");
Daniel Veillard652327a2003-09-29 18:02:38 +00003049#endif /* LIBXML_TREE_ENABLED */
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003050 fprintf(f, "\t--recover : output what was parsable on broken XML documents\n");
3051 fprintf(f, "\t--huge : remove any internal arbitrary parser limits\n");
3052 fprintf(f, "\t--noent : substitute entity references by their value\n");
3053 fprintf(f, "\t--noenc : ignore any encoding specified inside the document\n");
3054 fprintf(f, "\t--noout : don't output the result tree\n");
3055 fprintf(f, "\t--path 'paths': provide a set of paths for resources\n");
3056 fprintf(f, "\t--load-trace : print trace of all external entities loaded\n");
3057 fprintf(f, "\t--nonet : refuse to fetch DTDs or entities over network\n");
3058 fprintf(f, "\t--nocompact : do not generate compact text nodes\n");
3059 fprintf(f, "\t--htmlout : output results as HTML\n");
3060 fprintf(f, "\t--nowrap : do not put HTML doc wrapper\n");
Daniel Veillard4432df22003-09-28 18:58:27 +00003061#ifdef LIBXML_VALID_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003062 fprintf(f, "\t--valid : validate the document in addition to std well-formed check\n");
3063 fprintf(f, "\t--postvalid : do a posteriori validation, i.e after parsing\n");
3064 fprintf(f, "\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
3065 fprintf(f, "\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
Daniel Veillard4432df22003-09-28 18:58:27 +00003066#endif /* LIBXML_VALID_ENABLED */
Haibo Huang735158e2021-02-23 17:48:08 -08003067 fprintf(f, "\t--quiet : be quiet when succeeded\n");
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003068 fprintf(f, "\t--timing : print some timings\n");
3069 fprintf(f, "\t--output file or -o file: save to a given file\n");
3070 fprintf(f, "\t--repeat : repeat 100 times, for timing or profiling\n");
3071 fprintf(f, "\t--insert : ad-hoc test for valid insertions\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003072#ifdef LIBXML_OUTPUT_ENABLED
Nick Wellnhofercb5541c2017-11-13 17:08:38 +01003073#ifdef LIBXML_ZLIB_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003074 fprintf(f, "\t--compress : turn on gzip compression of output\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003075#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003076#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003077#ifdef LIBXML_HTML_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003078 fprintf(f, "\t--html : use the HTML parser\n");
3079 fprintf(f, "\t--xmlout : force to use the XML serializer when using --html\n");
3080 fprintf(f, "\t--nodefdtd : do not default HTML doctype\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003081#endif
Daniel Veillard73b013f2003-09-30 12:36:01 +00003082#ifdef LIBXML_PUSH_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003083 fprintf(f, "\t--push : use the push mode of the parser\n");
3084 fprintf(f, "\t--pushsmall : use the push mode of the parser using tiny increments\n");
Daniel Veillard73b013f2003-09-30 12:36:01 +00003085#endif /* LIBXML_PUSH_ENABLED */
Daniel Richard G5706b6d2012-08-06 11:32:54 +08003086#ifdef HAVE_MMAP
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003087 fprintf(f, "\t--memory : parse from memory\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003088#endif
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003089 fprintf(f, "\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n");
3090 fprintf(f, "\t--nowarning : do not emit warnings from parser/validator\n");
3091 fprintf(f, "\t--noblanks : drop (ignorable?) blanks spaces\n");
3092 fprintf(f, "\t--nocdata : replace cdata section with text nodes\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003093#ifdef LIBXML_OUTPUT_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003094 fprintf(f, "\t--format : reformat/reindent the output\n");
3095 fprintf(f, "\t--encode encoding : output in the given encoding\n");
3096 fprintf(f, "\t--dropdtd : remove the DOCTYPE of the input docs\n");
3097 fprintf(f, "\t--pretty STYLE : pretty-print in a particular style\n");
3098 fprintf(f, "\t 0 Do not pretty print\n");
3099 fprintf(f, "\t 1 Format the XML content, as --format\n");
3100 fprintf(f, "\t 2 Add whitespace inside tags, preserving content\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003101#endif /* LIBXML_OUTPUT_ENABLED */
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003102 fprintf(f, "\t--c14n : save in W3C canonical format v1.0 (with comments)\n");
3103 fprintf(f, "\t--c14n11 : save in W3C canonical format v1.1 (with comments)\n");
3104 fprintf(f, "\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n");
Daniel Veillard25048d82004-08-14 22:37:54 +00003105#ifdef LIBXML_C14N_ENABLED
3106#endif /* LIBXML_C14N_ENABLED */
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003107 fprintf(f, "\t--nsclean : remove redundant namespace declarations\n");
3108 fprintf(f, "\t--testIO : test user I/O support\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003109#ifdef LIBXML_CATALOG_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003110 fprintf(f, "\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
3111 fprintf(f, "\t otherwise XML Catalogs starting from \n");
3112 fprintf(f, "\t %s are activated by default\n", XML_XML_DEFAULT_CATALOG);
3113 fprintf(f, "\t--nocatalogs: deactivate all catalogs\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003114#endif
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003115 fprintf(f, "\t--auto : generate a small doc on the fly\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003116#ifdef LIBXML_XINCLUDE_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003117 fprintf(f, "\t--xinclude : do XInclude processing\n");
3118 fprintf(f, "\t--noxincludenode : same but do not generate XInclude nodes\n");
3119 fprintf(f, "\t--nofixup-base-uris : do not fixup xml:base uris\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003120#endif
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003121 fprintf(f, "\t--loaddtd : fetch external DTD\n");
3122 fprintf(f, "\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
Daniel Veillard81273902003-09-30 00:43:48 +00003123#ifdef LIBXML_READER_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003124 fprintf(f, "\t--stream : use the streaming interface to process very large files\n");
3125 fprintf(f, "\t--walker : create a reader and walk though the resulting doc\n");
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003126#ifdef LIBXML_PATTERN_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003127 fprintf(f, "\t--pattern pattern_value : test the pattern support\n");
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003128#endif
Haibo Huangcfd91dc2020-07-30 23:01:33 -07003129#endif /* LIBXML_READER_ENABLED */
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003130 fprintf(f, "\t--chkregister : verify the node registration code\n");
Daniel Veillardef4d3bc2003-02-07 12:38:22 +00003131#ifdef LIBXML_SCHEMAS_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003132 fprintf(f, "\t--relaxng schema : do RelaxNG validation against the schema\n");
3133 fprintf(f, "\t--schema schema : do validation against the WXS schema\n");
Daniel Veillard71531f32003-02-05 13:19:53 +00003134#endif
Daniel Veillarde70375c2005-07-30 21:09:12 +00003135#ifdef LIBXML_SCHEMATRON_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003136 fprintf(f, "\t--schematron schema : do validation against a schematron\n");
Daniel Veillarde70375c2005-07-30 21:09:12 +00003137#endif
Daniel Veillard971771e2005-07-09 17:32:57 +00003138#ifdef LIBXML_SAX1_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003139 fprintf(f, "\t--sax1: use the old SAX1 interfaces for processing\n");
Daniel Veillard971771e2005-07-09 17:32:57 +00003140#endif
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003141 fprintf(f, "\t--sax: do not build a tree but work just at the SAX level\n");
3142 fprintf(f, "\t--oldxml10: use XML-1.0 parsing rules before the 5th edition\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003143#ifdef LIBXML_XPATH_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003144 fprintf(f, "\t--xpath expr: evaluate the XPath expression, imply --noout\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003145#endif
Daniel Veillard971771e2005-07-09 17:32:57 +00003146
Elliott Hughesecdab2a2022-02-23 14:33:50 -08003147 fprintf(f, "\nLibxml project home page: https://gitlab.gnome.org/GNOME/libxml2\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003148}
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003149
3150static void registerNode(xmlNodePtr node)
3151{
3152 node->_private = malloc(sizeof(long));
Daniel Veillarde71dce12013-07-11 15:41:22 +08003153 if (node->_private == NULL) {
3154 fprintf(stderr, "Out of memory in xmllint:registerNode()\n");
3155 exit(XMLLINT_ERR_MEM);
3156 }
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003157 *(long*)node->_private = (long) 0x81726354;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003158 nbregister++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003159}
3160
3161static void deregisterNode(xmlNodePtr node)
3162{
3163 assert(node->_private != NULL);
3164 assert(*(long*)node->_private == (long) 0x81726354);
3165 free(node->_private);
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003166 nbregister--;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003167}
3168
Daniel Veillard4a6845d2001-01-03 13:32:39 +00003169int
3170main(int argc, char **argv) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00003171 int i, acount;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003172 int files = 0;
Daniel Veillard845cce42002-01-09 11:51:37 +00003173 int version = 0;
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00003174 const char* indent;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003175
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003176 if (argc <= 1) {
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003177 usage(stderr, argv[0]);
Elliott Hughesecdab2a2022-02-23 14:33:50 -08003178 return(XMLLINT_ERR_UNCLASS);
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003179 }
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003180
Elliott Hughesecdab2a2022-02-23 14:33:50 -08003181 /* xmlMemSetup must be called before initializing the parser. */
3182 for (i = 1; i < argc ; i++) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003183 if (argv[i][0] != '-')
3184 continue;
Elliott Hughesecdab2a2022-02-23 14:33:50 -08003185
3186 if ((!strcmp(argv[i], "-maxmem")) ||
3187 (!strcmp(argv[i], "--maxmem"))) {
3188 i++;
3189 if ((i >= argc) || (sscanf(argv[i], "%d", &maxmem) != 1)) {
3190 maxmem = 0;
3191 }
3192 }
3193 }
3194 if (maxmem != 0)
3195 xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc, myStrdupFunc);
3196
3197 LIBXML_TEST_VERSION
3198
3199 for (i = 1; i < argc ; i++) {
3200 if (argv[i][0] != '-' || argv[i][1] == 0)
3201 continue;
3202
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003203 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
3204 debug++;
Daniel Veillard56ada1d2003-01-07 11:17:25 +00003205 else
3206#ifdef LIBXML_DEBUG_ENABLED
3207 if ((!strcmp(argv[i], "-shell")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003208 (!strcmp(argv[i], "--shell"))) {
3209 shell++;
3210 noout = 1;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003211 } else
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003212#endif
Daniel Veillard652327a2003-09-29 18:02:38 +00003213#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003214 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
3215 copy++;
Daniel Veillard652327a2003-09-29 18:02:38 +00003216 else
3217#endif /* LIBXML_TREE_ENABLED */
3218 if ((!strcmp(argv[i], "-recover")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003219 (!strcmp(argv[i], "--recover"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003220 recovery++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003221 options |= XML_PARSE_RECOVER;
Daniel Veillard8915c152008-08-26 13:05:34 +00003222 } else if ((!strcmp(argv[i], "-huge")) ||
3223 (!strcmp(argv[i], "--huge"))) {
3224 options |= XML_PARSE_HUGE;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003225 } else if ((!strcmp(argv[i], "-noent")) ||
3226 (!strcmp(argv[i], "--noent"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003227 noent++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003228 options |= XML_PARSE_NOENT;
Daniel Veillardc62efc82011-05-16 16:03:50 +08003229 } else if ((!strcmp(argv[i], "-noenc")) ||
3230 (!strcmp(argv[i], "--noenc"))) {
3231 noenc++;
3232 options |= XML_PARSE_IGNORE_ENC;
Daniel Veillarddca8cc72003-09-26 13:53:14 +00003233 } else if ((!strcmp(argv[i], "-nsclean")) ||
3234 (!strcmp(argv[i], "--nsclean"))) {
3235 options |= XML_PARSE_NSCLEAN;
3236 } else if ((!strcmp(argv[i], "-nocdata")) ||
3237 (!strcmp(argv[i], "--nocdata"))) {
3238 options |= XML_PARSE_NOCDATA;
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003239 } else if ((!strcmp(argv[i], "-nodict")) ||
3240 (!strcmp(argv[i], "--nodict"))) {
3241 options |= XML_PARSE_NODICT;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003242 } else if ((!strcmp(argv[i], "-version")) ||
Daniel Veillard845cce42002-01-09 11:51:37 +00003243 (!strcmp(argv[i], "--version"))) {
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00003244 showVersion(argv[0]);
Daniel Veillard845cce42002-01-09 11:51:37 +00003245 version = 1;
3246 } else if ((!strcmp(argv[i], "-noout")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003247 (!strcmp(argv[i], "--noout")))
3248 noout++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003249#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003250 else if ((!strcmp(argv[i], "-o")) ||
3251 (!strcmp(argv[i], "-output")) ||
3252 (!strcmp(argv[i], "--output"))) {
3253 i++;
Daniel Veillard6e4f1c02002-04-09 09:55:20 +00003254 output = argv[i];
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003255 }
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003256#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003257 else if ((!strcmp(argv[i], "-htmlout")) ||
3258 (!strcmp(argv[i], "--htmlout")))
3259 htmlout++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003260 else if ((!strcmp(argv[i], "-nowrap")) ||
3261 (!strcmp(argv[i], "--nowrap")))
3262 nowrap++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003263#ifdef LIBXML_HTML_ENABLED
3264 else if ((!strcmp(argv[i], "-html")) ||
3265 (!strcmp(argv[i], "--html"))) {
3266 html++;
3267 }
Daniel Veillard42fd4122003-11-04 08:47:48 +00003268 else if ((!strcmp(argv[i], "-xmlout")) ||
3269 (!strcmp(argv[i], "--xmlout"))) {
3270 xmlout++;
Daniel Veillardf1121c42010-07-26 14:02:42 +02003271 } else if ((!strcmp(argv[i], "-nodefdtd")) ||
3272 (!strcmp(argv[i], "--nodefdtd"))) {
3273 nodefdtd++;
3274 options |= HTML_PARSE_NODEFDTD;
Daniel Veillard42fd4122003-11-04 08:47:48 +00003275 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003276#endif /* LIBXML_HTML_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003277 else if ((!strcmp(argv[i], "-loaddtd")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003278 (!strcmp(argv[i], "--loaddtd"))) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003279 loaddtd++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003280 options |= XML_PARSE_DTDLOAD;
3281 } else if ((!strcmp(argv[i], "-dtdattr")) ||
Daniel Veillard48da9102001-08-07 01:10:10 +00003282 (!strcmp(argv[i], "--dtdattr"))) {
3283 loaddtd++;
3284 dtdattrs++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003285 options |= XML_PARSE_DTDATTR;
Daniel Veillard4432df22003-09-28 18:58:27 +00003286 }
3287#ifdef LIBXML_VALID_ENABLED
3288 else if ((!strcmp(argv[i], "-valid")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003289 (!strcmp(argv[i], "--valid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003290 valid++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003291 options |= XML_PARSE_DTDVALID;
3292 } else if ((!strcmp(argv[i], "-postvalid")) ||
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003293 (!strcmp(argv[i], "--postvalid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003294 postvalid++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003295 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003296 options |= XML_PARSE_DTDLOAD;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003297 } else if ((!strcmp(argv[i], "-dtdvalid")) ||
Daniel Veillardcd429612000-10-11 15:57:05 +00003298 (!strcmp(argv[i], "--dtdvalid"))) {
3299 i++;
3300 dtdvalid = argv[i];
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003301 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003302 options |= XML_PARSE_DTDLOAD;
Daniel Veillard66f68e72003-08-18 16:39:51 +00003303 } else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3304 (!strcmp(argv[i], "--dtdvalidfpi"))) {
3305 i++;
3306 dtdvalidfpi = argv[i];
3307 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003308 options |= XML_PARSE_DTDLOAD;
Daniel Veillardcd429612000-10-11 15:57:05 +00003309 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003310#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard29e43992001-12-13 22:21:58 +00003311 else if ((!strcmp(argv[i], "-dropdtd")) ||
3312 (!strcmp(argv[i], "--dropdtd")))
3313 dropdtd++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003314 else if ((!strcmp(argv[i], "-insert")) ||
3315 (!strcmp(argv[i], "--insert")))
3316 insert++;
Haibo Huang735158e2021-02-23 17:48:08 -08003317 else if ((!strcmp(argv[i], "-quiet")) ||
3318 (!strcmp(argv[i], "--quiet")))
3319 quiet++;
Daniel Veillard48b2f892001-02-25 16:11:03 +00003320 else if ((!strcmp(argv[i], "-timing")) ||
3321 (!strcmp(argv[i], "--timing")))
3322 timing++;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00003323 else if ((!strcmp(argv[i], "-auto")) ||
3324 (!strcmp(argv[i], "--auto")))
3325 generate++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003326 else if ((!strcmp(argv[i], "-repeat")) ||
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00003327 (!strcmp(argv[i], "--repeat"))) {
3328 if (repeat)
3329 repeat *= 10;
3330 else
3331 repeat = 100;
Daniel Veillard73b013f2003-09-30 12:36:01 +00003332 }
3333#ifdef LIBXML_PUSH_ENABLED
3334 else if ((!strcmp(argv[i], "-push")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003335 (!strcmp(argv[i], "--push")))
3336 push++;
Daniel Veillard1abd2212012-10-25 15:37:50 +08003337 else if ((!strcmp(argv[i], "-pushsmall")) ||
3338 (!strcmp(argv[i], "--pushsmall"))) {
3339 push++;
3340 pushsize = 10;
3341 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00003342#endif /* LIBXML_PUSH_ENABLED */
Daniel Richard G5706b6d2012-08-06 11:32:54 +08003343#ifdef HAVE_MMAP
Daniel Veillard46e370e2000-07-21 20:32:03 +00003344 else if ((!strcmp(argv[i], "-memory")) ||
3345 (!strcmp(argv[i], "--memory")))
3346 memory++;
3347#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +00003348 else if ((!strcmp(argv[i], "-testIO")) ||
3349 (!strcmp(argv[i], "--testIO")))
3350 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003351#ifdef LIBXML_XINCLUDE_ENABLED
3352 else if ((!strcmp(argv[i], "-xinclude")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003353 (!strcmp(argv[i], "--xinclude"))) {
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003354 xinclude++;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003355 options |= XML_PARSE_XINCLUDE;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003356 }
Daniel Veillardc14c3892004-08-16 12:34:50 +00003357 else if ((!strcmp(argv[i], "-noxincludenode")) ||
3358 (!strcmp(argv[i], "--noxincludenode"))) {
3359 xinclude++;
3360 options |= XML_PARSE_XINCLUDE;
3361 options |= XML_PARSE_NOXINCNODE;
3362 }
Daniel Veillard54bd29b2008-08-26 07:26:55 +00003363 else if ((!strcmp(argv[i], "-nofixup-base-uris")) ||
3364 (!strcmp(argv[i], "--nofixup-base-uris"))) {
3365 xinclude++;
3366 options |= XML_PARSE_XINCLUDE;
3367 options |= XML_PARSE_NOBASEFIX;
3368 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003369#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003370#ifdef LIBXML_OUTPUT_ENABLED
Nick Wellnhofercb5541c2017-11-13 17:08:38 +01003371#ifdef LIBXML_ZLIB_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003372 else if ((!strcmp(argv[i], "-compress")) ||
3373 (!strcmp(argv[i], "--compress"))) {
3374 compress++;
3375 xmlSetCompressMode(9);
3376 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003377#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003378#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003379 else if ((!strcmp(argv[i], "-nowarning")) ||
3380 (!strcmp(argv[i], "--nowarning"))) {
3381 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003382 xmlPedanticParserDefault(0);
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003383 options |= XML_PARSE_NOWARNING;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003384 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003385 else if ((!strcmp(argv[i], "-pedantic")) ||
3386 (!strcmp(argv[i], "--pedantic"))) {
3387 xmlGetWarningsDefaultValue = 1;
3388 xmlPedanticParserDefault(1);
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003389 options |= XML_PARSE_PEDANTIC;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003390 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00003391#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003392 else if ((!strcmp(argv[i], "-debugent")) ||
3393 (!strcmp(argv[i], "--debugent"))) {
3394 debugent++;
3395 xmlParserDebugEntities = 1;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003396 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00003397#endif
Daniel Veillard25048d82004-08-14 22:37:54 +00003398#ifdef LIBXML_C14N_ENABLED
3399 else if ((!strcmp(argv[i], "-c14n")) ||
3400 (!strcmp(argv[i], "--c14n"))) {
3401 canonical++;
3402 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003403 }
Aleksey Sanin83868242009-07-09 10:26:22 +02003404 else if ((!strcmp(argv[i], "-c14n11")) ||
3405 (!strcmp(argv[i], "--c14n11"))) {
3406 canonical_11++;
3407 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003408 }
Aleksey Sanin2650df12005-06-06 17:16:50 +00003409 else if ((!strcmp(argv[i], "-exc-c14n")) ||
3410 (!strcmp(argv[i], "--exc-c14n"))) {
3411 exc_canonical++;
3412 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003413 }
Daniel Veillard25048d82004-08-14 22:37:54 +00003414#endif
Daniel Veillard81418e32001-05-22 15:08:55 +00003415#ifdef LIBXML_CATALOG_ENABLED
3416 else if ((!strcmp(argv[i], "-catalogs")) ||
3417 (!strcmp(argv[i], "--catalogs"))) {
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003418 catalogs++;
3419 } else if ((!strcmp(argv[i], "-nocatalogs")) ||
3420 (!strcmp(argv[i], "--nocatalogs"))) {
3421 nocatalogs++;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003422 }
Daniel Veillard81418e32001-05-22 15:08:55 +00003423#endif
Daniel Veillardbe803962000-06-28 23:40:59 +00003424 else if ((!strcmp(argv[i], "-encode")) ||
3425 (!strcmp(argv[i], "--encode"))) {
3426 i++;
3427 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003428 /*
3429 * OK it's for testing purposes
3430 */
3431 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +00003432 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003433 else if ((!strcmp(argv[i], "-noblanks")) ||
3434 (!strcmp(argv[i], "--noblanks"))) {
Daniel Veillardf933c892012-09-07 19:32:12 +08003435 noblanks++;
3436 xmlKeepBlanksDefault(0);
3437 options |= XML_PARSE_NOBLANKS;
Daniel Veillard90493a92001-08-14 14:12:47 +00003438 }
Daniel Veillard87076042004-05-03 22:54:49 +00003439 else if ((!strcmp(argv[i], "-maxmem")) ||
3440 (!strcmp(argv[i], "--maxmem"))) {
3441 i++;
Daniel Veillard87076042004-05-03 22:54:49 +00003442 }
Daniel Veillard90493a92001-08-14 14:12:47 +00003443 else if ((!strcmp(argv[i], "-format")) ||
3444 (!strcmp(argv[i], "--format"))) {
3445 noblanks++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003446#ifdef LIBXML_OUTPUT_ENABLED
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01003447 format = 1;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003448#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard90493a92001-08-14 14:12:47 +00003449 xmlKeepBlanksDefault(0);
Daniel Veillard7704fb12003-01-03 16:19:51 +00003450 }
Adam Spraggd2e62312010-11-03 15:33:40 +01003451 else if ((!strcmp(argv[i], "-pretty")) ||
3452 (!strcmp(argv[i], "--pretty"))) {
3453 i++;
3454#ifdef LIBXML_OUTPUT_ENABLED
Tim Galeckas2205ff42013-08-29 16:44:33 +08003455 if (argv[i] != NULL) {
3456 format = atoi(argv[i]);
3457 if (format == 1) {
3458 noblanks++;
3459 xmlKeepBlanksDefault(0);
3460 }
3461 }
Brandon Slack0c7109c2012-05-11 10:50:59 +08003462#endif /* LIBXML_OUTPUT_ENABLED */
Adam Spraggd2e62312010-11-03 15:33:40 +01003463 }
Daniel Veillard81273902003-09-30 00:43:48 +00003464#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003465 else if ((!strcmp(argv[i], "-stream")) ||
3466 (!strcmp(argv[i], "--stream"))) {
3467 stream++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003468 }
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003469 else if ((!strcmp(argv[i], "-walker")) ||
3470 (!strcmp(argv[i], "--walker"))) {
3471 walker++;
3472 noout++;
Haibo Huangcfd91dc2020-07-30 23:01:33 -07003473#ifdef LIBXML_PATTERN_ENABLED
3474 } else if ((!strcmp(argv[i], "-pattern")) ||
3475 (!strcmp(argv[i], "--pattern"))) {
3476 i++;
3477 pattern = argv[i];
3478#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003479 }
Daniel Veillard81273902003-09-30 00:43:48 +00003480#endif /* LIBXML_READER_ENABLED */
3481#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +00003482 else if ((!strcmp(argv[i], "-sax1")) ||
3483 (!strcmp(argv[i], "--sax1"))) {
Daniel Veillard023d0ba2009-07-29 11:34:50 +02003484 sax1++;
3485 options |= XML_PARSE_SAX1;
Daniel Veillard07cb8222003-09-10 10:51:05 +00003486 }
Daniel Veillard81273902003-09-30 00:43:48 +00003487#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003488 else if ((!strcmp(argv[i], "-sax")) ||
3489 (!strcmp(argv[i], "--sax"))) {
Daniel Veillard023d0ba2009-07-29 11:34:50 +02003490 sax++;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003491 }
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003492 else if ((!strcmp(argv[i], "-chkregister")) ||
3493 (!strcmp(argv[i], "--chkregister"))) {
Daniel Veillard023d0ba2009-07-29 11:34:50 +02003494 chkregister++;
Daniel Veillard71531f32003-02-05 13:19:53 +00003495#ifdef LIBXML_SCHEMAS_ENABLED
3496 } else if ((!strcmp(argv[i], "-relaxng")) ||
3497 (!strcmp(argv[i], "--relaxng"))) {
3498 i++;
3499 relaxng = argv[i];
3500 noent++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003501 options |= XML_PARSE_NOENT;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003502 } else if ((!strcmp(argv[i], "-schema")) ||
3503 (!strcmp(argv[i], "--schema"))) {
3504 i++;
3505 schema = argv[i];
3506 noent++;
Daniel Veillard71531f32003-02-05 13:19:53 +00003507#endif
Daniel Veillardd4501d72005-07-24 14:27:16 +00003508#ifdef LIBXML_SCHEMATRON_ENABLED
3509 } else if ((!strcmp(argv[i], "-schematron")) ||
3510 (!strcmp(argv[i], "--schematron"))) {
3511 i++;
3512 schematron = argv[i];
3513 noent++;
3514#endif
Daniel Veillarde8b09e42003-05-13 22:14:13 +00003515 } else if ((!strcmp(argv[i], "-nonet")) ||
3516 (!strcmp(argv[i], "--nonet"))) {
Daniel Veillard61b93382003-11-03 14:28:31 +00003517 options |= XML_PARSE_NONET;
Daniel Veillard968d6432006-04-25 16:17:53 +00003518 xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
Daniel Veillard8874b942005-08-25 13:19:21 +00003519 } else if ((!strcmp(argv[i], "-nocompact")) ||
3520 (!strcmp(argv[i], "--nocompact"))) {
3521 options &= ~XML_PARSE_COMPACT;
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003522 } else if ((!strcmp(argv[i], "-load-trace")) ||
3523 (!strcmp(argv[i], "--load-trace"))) {
3524 load_trace++;
3525 } else if ((!strcmp(argv[i], "-path")) ||
3526 (!strcmp(argv[i], "--path"))) {
3527 i++;
3528 parsePath(BAD_CAST argv[i]);
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003529#ifdef LIBXML_XPATH_ENABLED
3530 } else if ((!strcmp(argv[i], "-xpath")) ||
3531 (!strcmp(argv[i], "--xpath"))) {
3532 i++;
3533 noout++;
3534 xpathquery = argv[i];
3535#endif
Daniel Veillard7e5c3f42008-07-29 16:12:31 +00003536 } else if ((!strcmp(argv[i], "-oldxml10")) ||
3537 (!strcmp(argv[i], "--oldxml10"))) {
3538 oldxml10++;
3539 options |= XML_PARSE_OLD10;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003540 } else {
3541 fprintf(stderr, "Unknown option %s\n", argv[i]);
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003542 usage(stderr, argv[0]);
Elliott Hughesecdab2a2022-02-23 14:33:50 -08003543 return(XMLLINT_ERR_UNCLASS);
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003544 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003545 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003546
3547#ifdef LIBXML_CATALOG_ENABLED
3548 if (nocatalogs == 0) {
3549 if (catalogs) {
3550 const char *catal;
3551
3552 catal = getenv("SGML_CATALOG_FILES");
Daniel Veillard6c5f9d12001-08-25 13:33:14 +00003553 if (catal != NULL) {
3554 xmlLoadCatalogs(catal);
3555 } else {
3556 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
3557 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003558 }
3559 }
3560#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003561
Daniel Veillard81273902003-09-30 00:43:48 +00003562#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +00003563 if (sax1)
3564 xmlSAXDefaultVersion(1);
3565 else
3566 xmlSAXDefaultVersion(2);
Daniel Veillard81273902003-09-30 00:43:48 +00003567#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillard07cb8222003-09-10 10:51:05 +00003568
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003569 if (chkregister) {
3570 xmlRegisterNodeDefault(registerNode);
3571 xmlDeregisterNodeDefault(deregisterNode);
3572 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02003573
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00003574 indent = getenv("XMLLINT_INDENT");
3575 if(indent != NULL) {
3576 xmlTreeIndentString = indent;
3577 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02003578
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003579
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003580 defaultEntityLoader = xmlGetExternalEntityLoader();
3581 xmlSetExternalEntityLoader(xmllintExternalEntityLoader);
3582
Daniel Veillardd9bad132001-07-23 19:39:43 +00003583 xmlLineNumbersDefault(1);
Daniel Veillard48da9102001-08-07 01:10:10 +00003584 if (loaddtd != 0)
3585 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
3586 if (dtdattrs)
3587 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003588 if (noent != 0) xmlSubstituteEntitiesDefault(1);
Daniel Veillard4432df22003-09-28 18:58:27 +00003589#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003590 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
Daniel Veillard4432df22003-09-28 18:58:27 +00003591#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003592 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003593 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003594 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003595 xmlGenericError(xmlGenericErrorContext,
3596 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
3597 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003598 "<html><head><title>%s output</title></head>\n",
3599 argv[0]);
Daniel Veillardf1edb102009-08-10 14:43:18 +02003600 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003601 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
3602 argv[0]);
3603 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003604
Daniel Veillardd4501d72005-07-24 14:27:16 +00003605#ifdef LIBXML_SCHEMATRON_ENABLED
3606 if ((schematron != NULL) && (sax == 0)
3607#ifdef LIBXML_READER_ENABLED
3608 && (stream == 0)
3609#endif /* LIBXML_READER_ENABLED */
3610 ) {
3611 xmlSchematronParserCtxtPtr ctxt;
3612
3613 /* forces loading the DTDs */
Daniel Veillardf1edb102009-08-10 14:43:18 +02003614 xmlLoadExtDtdDefaultValue |= 1;
Daniel Veillardd4501d72005-07-24 14:27:16 +00003615 options |= XML_PARSE_DTDLOAD;
3616 if (timing) {
3617 startTimer();
3618 }
3619 ctxt = xmlSchematronNewParserCtxt(schematron);
Elliott Hughesecdab2a2022-02-23 14:33:50 -08003620 if (ctxt == NULL) {
3621 progresult = XMLLINT_ERR_MEM;
3622 goto error;
3623 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00003624#if 0
Haibo Huangcfd91dc2020-07-30 23:01:33 -07003625 xmlSchematronSetParserErrors(ctxt, xmlGenericError, xmlGenericError,
3626 NULL);
Daniel Veillardd4501d72005-07-24 14:27:16 +00003627#endif
3628 wxschematron = xmlSchematronParse(ctxt);
3629 if (wxschematron == NULL) {
3630 xmlGenericError(xmlGenericErrorContext,
3631 "Schematron schema %s failed to compile\n", schematron);
3632 progresult = XMLLINT_ERR_SCHEMACOMP;
3633 schematron = NULL;
3634 }
3635 xmlSchematronFreeParserCtxt(ctxt);
3636 if (timing) {
3637 endTimer("Compiling the schemas");
3638 }
3639 }
3640#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00003641#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003642 if ((relaxng != NULL) && (sax == 0)
Daniel Veillard81273902003-09-30 00:43:48 +00003643#ifdef LIBXML_READER_ENABLED
3644 && (stream == 0)
3645#endif /* LIBXML_READER_ENABLED */
3646 ) {
Daniel Veillard71531f32003-02-05 13:19:53 +00003647 xmlRelaxNGParserCtxtPtr ctxt;
3648
Daniel Veillardce192eb2003-04-16 15:58:05 +00003649 /* forces loading the DTDs */
Daniel Veillardf1edb102009-08-10 14:43:18 +02003650 xmlLoadExtDtdDefaultValue |= 1;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003651 options |= XML_PARSE_DTDLOAD;
Daniel Veillard42f12e92003-03-07 18:32:59 +00003652 if (timing) {
3653 startTimer();
3654 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003655 ctxt = xmlRelaxNGNewParserCtxt(relaxng);
Elliott Hughesecdab2a2022-02-23 14:33:50 -08003656 if (ctxt == NULL) {
3657 progresult = XMLLINT_ERR_MEM;
3658 goto error;
3659 }
Haibo Huangcfd91dc2020-07-30 23:01:33 -07003660 xmlRelaxNGSetParserErrors(ctxt, xmlGenericError, xmlGenericError,
3661 NULL);
Daniel Veillard71531f32003-02-05 13:19:53 +00003662 relaxngschemas = xmlRelaxNGParse(ctxt);
Daniel Veillardce192eb2003-04-16 15:58:05 +00003663 if (relaxngschemas == NULL) {
3664 xmlGenericError(xmlGenericErrorContext,
3665 "Relax-NG schema %s failed to compile\n", relaxng);
William M. Brack8304d872004-06-08 13:29:32 +00003666 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillardce192eb2003-04-16 15:58:05 +00003667 relaxng = NULL;
3668 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003669 xmlRelaxNGFreeParserCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00003670 if (timing) {
3671 endTimer("Compiling the schemas");
3672 }
Daniel Veillardebe25d42004-03-25 09:35:49 +00003673 } else if ((schema != NULL)
3674#ifdef LIBXML_READER_ENABLED
Daniel Veillardf10ae122005-07-10 19:03:16 +00003675 && (stream == 0)
Daniel Veillardebe25d42004-03-25 09:35:49 +00003676#endif
3677 ) {
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003678 xmlSchemaParserCtxtPtr ctxt;
3679
3680 if (timing) {
3681 startTimer();
3682 }
3683 ctxt = xmlSchemaNewParserCtxt(schema);
Elliott Hughesecdab2a2022-02-23 14:33:50 -08003684 if (ctxt == NULL) {
3685 progresult = XMLLINT_ERR_MEM;
3686 goto error;
3687 }
Haibo Huangcfd91dc2020-07-30 23:01:33 -07003688 xmlSchemaSetParserErrors(ctxt, xmlGenericError, xmlGenericError, NULL);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003689 wxschemas = xmlSchemaParse(ctxt);
3690 if (wxschemas == NULL) {
3691 xmlGenericError(xmlGenericErrorContext,
3692 "WXS schema %s failed to compile\n", schema);
William M. Brack8304d872004-06-08 13:29:32 +00003693 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003694 schema = NULL;
3695 }
3696 xmlSchemaFreeParserCtxt(ctxt);
3697 if (timing) {
3698 endTimer("Compiling the schemas");
3699 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003700 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003701#endif /* LIBXML_SCHEMAS_ENABLED */
Haibo Huangcfd91dc2020-07-30 23:01:33 -07003702#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
3703 if ((pattern != NULL) && (walker == 0)) {
Daniel Veillardffa7b7e2003-12-05 16:10:21 +00003704 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003705 if (patternc == NULL) {
3706 xmlGenericError(xmlGenericErrorContext,
3707 "Pattern %s failed to compile\n", pattern);
William M. Brack8304d872004-06-08 13:29:32 +00003708 progresult = XMLLINT_ERR_SCHEMAPAT;
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003709 pattern = NULL;
3710 }
3711 }
Haibo Huangcfd91dc2020-07-30 23:01:33 -07003712#endif /* LIBXML_READER_ENABLED && LIBXML_PATTERN_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003713 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +00003714 if ((!strcmp(argv[i], "-encode")) ||
3715 (!strcmp(argv[i], "--encode"))) {
3716 i++;
3717 continue;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003718 } else if ((!strcmp(argv[i], "-o")) ||
3719 (!strcmp(argv[i], "-output")) ||
3720 (!strcmp(argv[i], "--output"))) {
3721 i++;
3722 continue;
Daniel Veillardbe803962000-06-28 23:40:59 +00003723 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003724#ifdef LIBXML_VALID_ENABLED
Daniel Veillardcd429612000-10-11 15:57:05 +00003725 if ((!strcmp(argv[i], "-dtdvalid")) ||
3726 (!strcmp(argv[i], "--dtdvalid"))) {
3727 i++;
3728 continue;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003729 }
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003730 if ((!strcmp(argv[i], "-path")) ||
3731 (!strcmp(argv[i], "--path"))) {
3732 i++;
3733 continue;
Daniel Veillardcd429612000-10-11 15:57:05 +00003734 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00003735 if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3736 (!strcmp(argv[i], "--dtdvalidfpi"))) {
3737 i++;
3738 continue;
3739 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003740#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard71531f32003-02-05 13:19:53 +00003741 if ((!strcmp(argv[i], "-relaxng")) ||
3742 (!strcmp(argv[i], "--relaxng"))) {
3743 i++;
3744 continue;
3745 }
Daniel Veillard87076042004-05-03 22:54:49 +00003746 if ((!strcmp(argv[i], "-maxmem")) ||
3747 (!strcmp(argv[i], "--maxmem"))) {
3748 i++;
3749 continue;
3750 }
Adam Spraggd2e62312010-11-03 15:33:40 +01003751 if ((!strcmp(argv[i], "-pretty")) ||
3752 (!strcmp(argv[i], "--pretty"))) {
3753 i++;
3754 continue;
3755 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003756 if ((!strcmp(argv[i], "-schema")) ||
3757 (!strcmp(argv[i], "--schema"))) {
3758 i++;
3759 continue;
3760 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00003761 if ((!strcmp(argv[i], "-schematron")) ||
3762 (!strcmp(argv[i], "--schematron"))) {
3763 i++;
3764 continue;
3765 }
Haibo Huangcfd91dc2020-07-30 23:01:33 -07003766#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003767 if ((!strcmp(argv[i], "-pattern")) ||
3768 (!strcmp(argv[i], "--pattern"))) {
3769 i++;
3770 continue;
3771 }
3772#endif
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003773#ifdef LIBXML_XPATH_ENABLED
3774 if ((!strcmp(argv[i], "-xpath")) ||
3775 (!strcmp(argv[i], "--xpath"))) {
3776 i++;
3777 continue;
3778 }
3779#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00003780 if ((timing) && (repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00003781 startTimer();
Daniel Veillardcbaf3992001-12-31 16:16:02 +00003782 /* Remember file names. "-" means stdin. <sven@zen.org> */
Daniel Veillard4a6845d2001-01-03 13:32:39 +00003783 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003784 if (repeat) {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003785 xmlParserCtxtPtr ctxt = NULL;
3786
3787 for (acount = 0;acount < repeat;acount++) {
Daniel Veillard81273902003-09-30 00:43:48 +00003788#ifdef LIBXML_READER_ENABLED
Daniel Veillard198c1bf2003-10-20 17:07:41 +00003789 if (stream != 0) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00003790 streamFile(argv[i]);
Daniel Veillard198c1bf2003-10-20 17:07:41 +00003791 } else {
Daniel Veillard81273902003-09-30 00:43:48 +00003792#endif /* LIBXML_READER_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003793 if (sax) {
3794 testSAX(argv[i]);
3795 } else {
3796 if (ctxt == NULL)
3797 ctxt = xmlNewParserCtxt();
3798 parseAndPrintFile(argv[i], ctxt);
3799 }
Daniel Veillard81273902003-09-30 00:43:48 +00003800#ifdef LIBXML_READER_ENABLED
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003801 }
Daniel Veillard81273902003-09-30 00:43:48 +00003802#endif /* LIBXML_READER_ENABLED */
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003803 }
3804 if (ctxt != NULL)
3805 xmlFreeParserCtxt(ctxt);
Daniel Veillard7704fb12003-01-03 16:19:51 +00003806 } else {
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003807 nbregister = 0;
3808
Daniel Veillard81273902003-09-30 00:43:48 +00003809#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003810 if (stream != 0)
3811 streamFile(argv[i]);
3812 else
Daniel Veillard81273902003-09-30 00:43:48 +00003813#endif /* LIBXML_READER_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003814 if (sax) {
3815 testSAX(argv[i]);
3816 } else {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003817 parseAndPrintFile(argv[i], NULL);
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003818 }
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003819
3820 if ((chkregister) && (nbregister != 0)) {
3821 fprintf(stderr, "Registration count off: %d\n", nbregister);
William M. Brack8304d872004-06-08 13:29:32 +00003822 progresult = XMLLINT_ERR_RDREGIS;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003823 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00003824 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003825 files ++;
Daniel Veillarda7866932001-12-04 13:14:44 +00003826 if ((timing) && (repeat)) {
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00003827 endTimer("%d iterations", repeat);
Daniel Veillarda7866932001-12-04 13:14:44 +00003828 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00003829 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003830 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02003831 if (generate)
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003832 parseAndPrintFile(NULL, NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003833 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003834 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003835 }
Daniel Veillard845cce42002-01-09 11:51:37 +00003836 if ((files == 0) && (!generate) && (version == 0)) {
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003837 usage(stderr, argv[0]);
Elliott Hughesecdab2a2022-02-23 14:33:50 -08003838 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003839 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00003840#ifdef LIBXML_SCHEMATRON_ENABLED
3841 if (wxschematron != NULL)
3842 xmlSchematronFree(wxschematron);
3843#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00003844#ifdef LIBXML_SCHEMAS_ENABLED
3845 if (relaxngschemas != NULL)
3846 xmlRelaxNGFree(relaxngschemas);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003847 if (wxschemas != NULL)
3848 xmlSchemaFree(wxschemas);
Daniel Veillard71531f32003-02-05 13:19:53 +00003849 xmlRelaxNGCleanupTypes();
3850#endif
Haibo Huangcfd91dc2020-07-30 23:01:33 -07003851#if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003852 if (patternc != NULL)
3853 xmlFreePattern(patternc);
3854#endif
Elliott Hughesecdab2a2022-02-23 14:33:50 -08003855
3856 /* Avoid unused label warning if features are disabled. */
3857 goto error;
3858
3859error:
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003860 xmlCleanupParser();
3861 xmlMemoryDump();
3862
Daniel Veillardf7cd4812001-02-23 18:44:52 +00003863 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003864}
Daniel Veillard88a172f2000-08-04 18:23:10 +00003865