blob: d6f5eb0e8e551851ef0407af56c075de99b85083 [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;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000168static int timing = 0;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000169static int generate = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000170static int dropdtd = 0;
Daniel Veillarde2940dd2001-08-22 00:06:49 +0000171#ifdef LIBXML_CATALOG_ENABLED
172static int catalogs = 0;
173static int nocatalogs = 0;
174#endif
Daniel Veillard25048d82004-08-14 22:37:54 +0000175#ifdef LIBXML_C14N_ENABLED
176static int canonical = 0;
Aleksey Sanin83868242009-07-09 10:26:22 +0200177static int canonical_11 = 0;
Aleksey Sanin2650df12005-06-06 17:16:50 +0000178static int exc_canonical = 0;
Daniel Veillard25048d82004-08-14 22:37:54 +0000179#endif
Daniel Veillard81273902003-09-30 00:43:48 +0000180#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +0000181static int stream = 0;
Daniel Veillard7899c5c2003-11-03 12:31:38 +0000182static int walker = 0;
Daniel Veillard81273902003-09-30 00:43:48 +0000183#endif /* LIBXML_READER_ENABLED */
Daniel Veillard8a1b1852003-01-05 22:37:17 +0000184static int chkregister = 0;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +0000185static int nbregister = 0;
Daniel Veillard81273902003-09-30 00:43:48 +0000186#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +0000187static int sax1 = 0;
Daniel Veillard81273902003-09-30 00:43:48 +0000188#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillardb3de70c2003-12-02 22:32:15 +0000189#ifdef LIBXML_PATTERN_ENABLED
190static const char *pattern = NULL;
191static xmlPatternPtr patternc = NULL;
Daniel Veillard2fc6df92005-01-30 18:42:55 +0000192static xmlStreamCtxtPtr patstream = NULL;
Daniel Veillardb3de70c2003-12-02 22:32:15 +0000193#endif
Daniel Veillard1934b0c2009-10-07 10:25:06 +0200194#ifdef LIBXML_XPATH_ENABLED
195static const char *xpathquery = NULL;
196#endif
Daniel Veillard968a03a2012-08-13 12:41:33 +0800197static int options = XML_PARSE_COMPACT | XML_PARSE_BIG_LINES;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000198static int sax = 0;
Daniel Veillard7e5c3f42008-07-29 16:12:31 +0000199static int oldxml10 = 0;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +0000200
Daniel Veillard87076042004-05-03 22:54:49 +0000201/************************************************************************
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000202 * *
203 * Entity loading control and customization. *
204 * *
205 ************************************************************************/
206#define MAX_PATHS 64
Daniel Veillarded121382007-04-17 12:33:19 +0000207#ifdef _WIN32
208# define PATH_SEPARATOR ';'
209#else
210# define PATH_SEPARATOR ':'
211#endif
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000212static xmlChar *paths[MAX_PATHS + 1];
213static int nbpaths = 0;
214static int load_trace = 0;
215
216static
217void parsePath(const xmlChar *path) {
218 const xmlChar *cur;
219
220 if (path == NULL)
221 return;
222 while (*path != 0) {
223 if (nbpaths >= MAX_PATHS) {
224 fprintf(stderr, "MAX_PATHS reached: too many paths\n");
225 return;
226 }
227 cur = path;
Daniel Veillarded121382007-04-17 12:33:19 +0000228 while ((*cur == ' ') || (*cur == PATH_SEPARATOR))
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000229 cur++;
230 path = cur;
Daniel Veillarded121382007-04-17 12:33:19 +0000231 while ((*cur != 0) && (*cur != ' ') && (*cur != PATH_SEPARATOR))
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000232 cur++;
233 if (cur != path) {
234 paths[nbpaths] = xmlStrndup(path, cur - path);
235 if (paths[nbpaths] != NULL)
236 nbpaths++;
237 path = cur;
238 }
239 }
240}
241
Daniel Veillard24505b02005-07-28 23:49:35 +0000242static xmlExternalEntityLoader defaultEntityLoader = NULL;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000243
Daniel Veillardf1edb102009-08-10 14:43:18 +0200244static xmlParserInputPtr
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000245xmllintExternalEntityLoader(const char *URL, const char *ID,
246 xmlParserCtxtPtr ctxt) {
247 xmlParserInputPtr ret;
248 warningSAXFunc warning = NULL;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000249 errorSAXFunc err = NULL;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000250
251 int i;
252 const char *lastsegment = URL;
253 const char *iter = URL;
254
Daniel Veillard5608b172008-01-11 06:53:15 +0000255 if ((nbpaths > 0) && (iter != NULL)) {
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000256 while (*iter != 0) {
257 if (*iter == '/')
258 lastsegment = iter + 1;
259 iter++;
260 }
261 }
262
263 if ((ctxt != NULL) && (ctxt->sax != NULL)) {
264 warning = ctxt->sax->warning;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000265 err = ctxt->sax->error;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000266 ctxt->sax->warning = NULL;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000267 ctxt->sax->error = NULL;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000268 }
269
270 if (defaultEntityLoader != NULL) {
271 ret = defaultEntityLoader(URL, ID, ctxt);
272 if (ret != NULL) {
273 if (warning != NULL)
274 ctxt->sax->warning = warning;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000275 if (err != NULL)
276 ctxt->sax->error = err;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000277 if (load_trace) {
278 fprintf \
279 (stderr,
280 "Loaded URL=\"%s\" ID=\"%s\"\n",
281 URL ? URL : "(null)",
282 ID ? ID : "(null)");
283 }
284 return(ret);
285 }
286 }
287 for (i = 0;i < nbpaths;i++) {
288 xmlChar *newURL;
289
290 newURL = xmlStrdup((const xmlChar *) paths[i]);
291 newURL = xmlStrcat(newURL, (const xmlChar *) "/");
292 newURL = xmlStrcat(newURL, (const xmlChar *) lastsegment);
293 if (newURL != NULL) {
294 ret = defaultEntityLoader((const char *)newURL, ID, ctxt);
295 if (ret != NULL) {
296 if (warning != NULL)
297 ctxt->sax->warning = warning;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000298 if (err != NULL)
299 ctxt->sax->error = err;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000300 if (load_trace) {
301 fprintf \
Daniel Veillardf1edb102009-08-10 14:43:18 +0200302 (stderr,
303 "Loaded URL=\"%s\" ID=\"%s\"\n",
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000304 newURL,
Daniel Veillardf1edb102009-08-10 14:43:18 +0200305 ID ? ID : "(null)");
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000306 }
307 xmlFree(newURL);
308 return(ret);
309 }
310 xmlFree(newURL);
311 }
312 }
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000313 if (err != NULL)
314 ctxt->sax->error = err;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000315 if (warning != NULL) {
316 ctxt->sax->warning = warning;
317 if (URL != NULL)
318 warning(ctxt, "failed to load external entity \"%s\"\n", URL);
319 else if (ID != NULL)
320 warning(ctxt, "failed to load external entity \"%s\"\n", ID);
321 }
322 return(NULL);
323}
324/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +0200325 * *
Daniel Veillard87076042004-05-03 22:54:49 +0000326 * Memory allocation consumption debugging *
Daniel Veillardf1edb102009-08-10 14:43:18 +0200327 * *
Daniel Veillard87076042004-05-03 22:54:49 +0000328 ************************************************************************/
329
Daniel Veillard3af3b592004-05-05 19:22:30 +0000330static void
331OOM(void)
332{
Daniel Veillard87076042004-05-03 22:54:49 +0000333 fprintf(stderr, "Ran out of memory needs > %d bytes\n", maxmem);
William M. Brack8304d872004-06-08 13:29:32 +0000334 progresult = XMLLINT_ERR_MEM;
Daniel Veillard87076042004-05-03 22:54:49 +0000335}
336
Daniel Veillard3af3b592004-05-05 19:22:30 +0000337static void
338myFreeFunc(void *mem)
339{
Daniel Veillard87076042004-05-03 22:54:49 +0000340 xmlMemFree(mem);
341}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000342static void *
343myMallocFunc(size_t size)
344{
Daniel Veillard87076042004-05-03 22:54:49 +0000345 void *ret;
346
347 ret = xmlMemMalloc(size);
348 if (ret != NULL) {
349 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000350 OOM();
351 xmlMemFree(ret);
352 return (NULL);
353 }
Daniel Veillard87076042004-05-03 22:54:49 +0000354 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000355 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000356}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000357static void *
358myReallocFunc(void *mem, size_t size)
359{
Daniel Veillard87076042004-05-03 22:54:49 +0000360 void *ret;
361
362 ret = xmlMemRealloc(mem, size);
363 if (ret != NULL) {
364 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000365 OOM();
366 xmlMemFree(ret);
367 return (NULL);
368 }
Daniel Veillard87076042004-05-03 22:54:49 +0000369 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000370 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000371}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000372static char *
373myStrdupFunc(const char *str)
374{
Daniel Veillard87076042004-05-03 22:54:49 +0000375 char *ret;
376
377 ret = xmlMemoryStrdup(str);
378 if (ret != NULL) {
379 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000380 OOM();
381 xmlFree(ret);
382 return (NULL);
383 }
Daniel Veillard87076042004-05-03 22:54:49 +0000384 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000385 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000386}
Daniel Veillard87076042004-05-03 22:54:49 +0000387/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +0200388 * *
Daniel Veillard87076042004-05-03 22:54:49 +0000389 * Internal timing routines to remove the necessity to have *
390 * unix-specific function calls. *
Daniel Veillardf1edb102009-08-10 14:43:18 +0200391 * *
Daniel Veillard87076042004-05-03 22:54:49 +0000392 ************************************************************************/
Daniel Veillard01db67c2001-12-18 07:09:59 +0000393
Daniel Veillardf1edb102009-08-10 14:43:18 +0200394#ifndef HAVE_GETTIMEOFDAY
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000395#ifdef HAVE_SYS_TIMEB_H
396#ifdef HAVE_SYS_TIME_H
397#ifdef HAVE_FTIME
398
Daniel Veillard01c13b52002-12-10 15:19:08 +0000399static int
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000400my_gettimeofday(struct timeval *tvp, void *tzp)
401{
402 struct timeb timebuffer;
403
404 ftime(&timebuffer);
405 if (tvp) {
406 tvp->tv_sec = timebuffer.time;
407 tvp->tv_usec = timebuffer.millitm * 1000L;
408 }
409 return (0);
410}
411#define HAVE_GETTIMEOFDAY 1
412#define gettimeofday my_gettimeofday
413
414#endif /* HAVE_FTIME */
415#endif /* HAVE_SYS_TIME_H */
416#endif /* HAVE_SYS_TIMEB_H */
417#endif /* !HAVE_GETTIMEOFDAY */
418
Daniel Veillard01db67c2001-12-18 07:09:59 +0000419#if defined(HAVE_GETTIMEOFDAY)
420static struct timeval begin, end;
421
422/*
423 * startTimer: call where you want to start timing
424 */
425static void
426startTimer(void)
427{
428 gettimeofday(&begin, NULL);
429}
430
431/*
432 * endTimer: call where you want to stop timing and to print out a
433 * message about the timing performed; format is a printf
434 * type argument
435 */
David Kilzer4472c3a2016-05-13 15:13:17 +0800436static void XMLCDECL LIBXML_ATTR_FORMAT(1,2)
Daniel Veillard118aed72002-09-24 14:13:13 +0000437endTimer(const char *fmt, ...)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000438{
439 long msec;
440 va_list ap;
441
442 gettimeofday(&end, NULL);
443 msec = end.tv_sec - begin.tv_sec;
444 msec *= 1000;
445 msec += (end.tv_usec - begin.tv_usec) / 1000;
446
447#ifndef HAVE_STDARG_H
448#error "endTimer required stdarg functions"
449#endif
Daniel Veillard118aed72002-09-24 14:13:13 +0000450 va_start(ap, fmt);
451 vfprintf(stderr, fmt, ap);
Daniel Veillard01db67c2001-12-18 07:09:59 +0000452 va_end(ap);
453
454 fprintf(stderr, " took %ld ms\n", msec);
455}
456#elif defined(HAVE_TIME_H)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000457/*
458 * No gettimeofday function, so we have to make do with calling clock.
459 * This is obviously less accurate, but there's little we can do about
460 * that.
461 */
Daniel Veillard90bc3712002-03-07 15:12:58 +0000462#ifndef CLOCKS_PER_SEC
463#define CLOCKS_PER_SEC 100
464#endif
Daniel Veillard01db67c2001-12-18 07:09:59 +0000465
466static clock_t begin, end;
467static void
468startTimer(void)
469{
470 begin = clock();
471}
David Kilzer4472c3a2016-05-13 15:13:17 +0800472static void XMLCDECL LIBXML_ATTR_FORMAT(1,2)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000473endTimer(const char *fmt, ...)
474{
475 long msec;
476 va_list ap;
477
478 end = clock();
479 msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
480
481#ifndef HAVE_STDARG_H
482#error "endTimer required stdarg functions"
483#endif
484 va_start(ap, fmt);
485 vfprintf(stderr, fmt, ap);
486 va_end(ap);
487 fprintf(stderr, " took %ld ms\n", msec);
488}
489#else
490
491/*
492 * We don't have a gettimeofday or time.h, so we just don't do timing
493 */
494static void
495startTimer(void)
496{
497 /*
498 * Do nothing
499 */
500}
David Kilzer4472c3a2016-05-13 15:13:17 +0800501static void XMLCDECL LIBXML_ATTR_FORMAT(1,2)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000502endTimer(char *format, ...)
503{
504 /*
505 * We cannot do anything because we don't have a timing function
506 */
507#ifdef HAVE_STDARG_H
Patrick R. Gansterer023206f2012-05-10 22:17:51 +0800508 va_list ap;
Daniel Veillard01db67c2001-12-18 07:09:59 +0000509 va_start(ap, format);
510 vfprintf(stderr, format, ap);
511 va_end(ap);
Patrick R. Gansterer023206f2012-05-10 22:17:51 +0800512 fprintf(stderr, " was not timed\n");
Daniel Veillard01db67c2001-12-18 07:09:59 +0000513#else
514 /* We don't have gettimeofday, time or stdarg.h, what crazy world is
515 * this ?!
516 */
517#endif
518}
519#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000520/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +0200521 * *
522 * HTML ouput *
523 * *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000524 ************************************************************************/
Daniel Veillard24505b02005-07-28 23:49:35 +0000525static char buffer[50000];
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000526
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000527static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000528xmlHTMLEncodeSend(void) {
529 char *result;
530
531 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
532 if (result) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000533 xmlGenericError(xmlGenericErrorContext, "%s", result);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000534 xmlFree(result);
535 }
536 buffer[0] = 0;
537}
538
539/**
540 * xmlHTMLPrintFileInfo:
541 * @input: an xmlParserInputPtr input
Daniel Veillardf1edb102009-08-10 14:43:18 +0200542 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000543 * Displays the associated file and line informations for the current input
544 */
545
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000546static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000547xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000548 int len;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000549 xmlGenericError(xmlGenericErrorContext, "<p>");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000550
551 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000552 if (input != NULL) {
553 if (input->filename) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000554 snprintf(&buffer[len], sizeof(buffer) - len, "%s:%d: ", input->filename,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000555 input->line);
556 } else {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000557 snprintf(&buffer[len], sizeof(buffer) - len, "Entity: line %d: ", input->line);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000558 }
559 }
560 xmlHTMLEncodeSend();
561}
562
563/**
564 * xmlHTMLPrintFileContext:
565 * @input: an xmlParserInputPtr input
Daniel Veillardf1edb102009-08-10 14:43:18 +0200566 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000567 * Displays current context within the input content for error tracking
568 */
569
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000570static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000571xmlHTMLPrintFileContext(xmlParserInputPtr input) {
572 const xmlChar *cur, *base;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000573 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000574 int n;
575
576 if (input == NULL) return;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000577 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000578 cur = input->cur;
579 base = input->base;
580 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
581 cur--;
582 }
583 n = 0;
584 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
585 cur--;
586 if ((*cur == '\n') || (*cur == '\r')) cur++;
587 base = cur;
588 n = 0;
589 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000590 len = strlen(buffer);
Daniel Veillardf1edb102009-08-10 14:43:18 +0200591 snprintf(&buffer[len], sizeof(buffer) - len, "%c",
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000592 (unsigned char) *cur++);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000593 n++;
594 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000595 len = strlen(buffer);
596 snprintf(&buffer[len], sizeof(buffer) - len, "\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000597 cur = input->cur;
598 while ((*cur == '\n') || (*cur == '\r'))
599 cur--;
600 n = 0;
601 while ((cur != base) && (n++ < 80)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000602 len = strlen(buffer);
603 snprintf(&buffer[len], sizeof(buffer) - len, " ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000604 base++;
605 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000606 len = strlen(buffer);
607 snprintf(&buffer[len], sizeof(buffer) - len, "^\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000608 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000609 xmlGenericError(xmlGenericErrorContext, "</pre>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000610}
611
612/**
613 * xmlHTMLError:
614 * @ctx: an XML parser context
615 * @msg: the message to display/transmit
616 * @...: extra parameters for the message display
Daniel Veillardf1edb102009-08-10 14:43:18 +0200617 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000618 * Display and format an error messages, gives file, line, position and
619 * extra parameters.
620 */
David Kilzer4472c3a2016-05-13 15:13:17 +0800621static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000622xmlHTMLError(void *ctx, const char *msg, ...)
623{
624 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
625 xmlParserInputPtr input;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000626 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000627 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000628
629 buffer[0] = 0;
630 input = ctxt->input;
631 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000632 input = ctxt->inputTab[ctxt->inputNr - 2];
633 }
Daniel Veillardf1edb102009-08-10 14:43:18 +0200634
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000635 xmlHTMLPrintFileInfo(input);
636
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000637 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000638 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000639 len = strlen(buffer);
640 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000641 va_end(args);
642 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000643 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000644
645 xmlHTMLPrintFileContext(input);
646 xmlHTMLEncodeSend();
647}
648
649/**
650 * xmlHTMLWarning:
651 * @ctx: an XML parser context
652 * @msg: the message to display/transmit
653 * @...: extra parameters for the message display
Daniel Veillardf1edb102009-08-10 14:43:18 +0200654 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000655 * Display and format a warning messages, gives file, line, position and
656 * extra parameters.
657 */
David Kilzer4472c3a2016-05-13 15:13:17 +0800658static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000659xmlHTMLWarning(void *ctx, const char *msg, ...)
660{
661 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
662 xmlParserInputPtr input;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000663 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000664 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000665
666 buffer[0] = 0;
667 input = ctxt->input;
668 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000669 input = ctxt->inputTab[ctxt->inputNr - 2];
670 }
Daniel Veillardf1edb102009-08-10 14:43:18 +0200671
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000672
673 xmlHTMLPrintFileInfo(input);
Daniel Veillardf1edb102009-08-10 14:43:18 +0200674
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000675 xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000676 va_start(args, msg);
Daniel Veillardf1edb102009-08-10 14:43:18 +0200677 len = strlen(buffer);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000678 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000679 va_end(args);
680 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000681 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000682
683 xmlHTMLPrintFileContext(input);
684 xmlHTMLEncodeSend();
685}
686
687/**
688 * xmlHTMLValidityError:
689 * @ctx: an XML parser context
690 * @msg: the message to display/transmit
691 * @...: extra parameters for the message display
Daniel Veillardf1edb102009-08-10 14:43:18 +0200692 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000693 * Display and format an validity error messages, gives file,
694 * line, position and extra parameters.
695 */
David Kilzer4472c3a2016-05-13 15:13:17 +0800696static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000697xmlHTMLValidityError(void *ctx, const char *msg, ...)
698{
699 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
700 xmlParserInputPtr input;
701 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000702 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000703
704 buffer[0] = 0;
705 input = ctxt->input;
706 if ((input->filename == NULL) && (ctxt->inputNr > 1))
707 input = ctxt->inputTab[ctxt->inputNr - 2];
Daniel Veillardf1edb102009-08-10 14:43:18 +0200708
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000709 xmlHTMLPrintFileInfo(input);
710
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000711 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000712 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000713 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000714 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000715 va_end(args);
716 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000717 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000718
719 xmlHTMLPrintFileContext(input);
720 xmlHTMLEncodeSend();
Daniel Veillard9fcb4912005-03-16 12:57:31 +0000721 progresult = XMLLINT_ERR_VALID;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000722}
723
724/**
725 * xmlHTMLValidityWarning:
726 * @ctx: an XML parser context
727 * @msg: the message to display/transmit
728 * @...: extra parameters for the message display
Daniel Veillardf1edb102009-08-10 14:43:18 +0200729 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000730 * Display and format a validity warning messages, gives file, line,
731 * position and extra parameters.
732 */
David Kilzer4472c3a2016-05-13 15:13:17 +0800733static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000734xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
735{
736 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
737 xmlParserInputPtr input;
738 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000739 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000740
741 buffer[0] = 0;
742 input = ctxt->input;
743 if ((input->filename == NULL) && (ctxt->inputNr > 1))
744 input = ctxt->inputTab[ctxt->inputNr - 2];
745
746 xmlHTMLPrintFileInfo(input);
Daniel Veillardf1edb102009-08-10 14:43:18 +0200747
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000748 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000749 va_start(args, msg);
Daniel Veillardf1edb102009-08-10 14:43:18 +0200750 len = strlen(buffer);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000751 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000752 va_end(args);
753 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000754 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000755
756 xmlHTMLPrintFileContext(input);
757 xmlHTMLEncodeSend();
758}
759
760/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +0200761 * *
762 * Shell Interface *
763 * *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000764 ************************************************************************/
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000765#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000766#ifdef LIBXML_XPATH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000767/**
768 * xmlShellReadline:
769 * @prompt: the prompt value
770 *
771 * Read a string
Daniel Veillardf1edb102009-08-10 14:43:18 +0200772 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000773 * Returns a pointer to it or NULL on EOF the caller is expected to
774 * free the returned string.
775 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000776static char *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000777xmlShellReadline(char *prompt) {
778#ifdef HAVE_LIBREADLINE
779 char *line_read;
780
781 /* Get a line from the user. */
782 line_read = readline (prompt);
783
784 /* If the line has any text in it, save it on the history. */
785 if (line_read && *line_read)
786 add_history (line_read);
787
788 return (line_read);
789#else
790 char line_read[501];
Daniel Veillard29e43992001-12-13 22:21:58 +0000791 char *ret;
792 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000793
794 if (prompt != NULL)
795 fprintf(stdout, "%s", prompt);
Patrick Monnerat11e805d2015-04-17 17:02:59 +0200796 fflush(stdout);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000797 if (!fgets(line_read, 500, stdin))
798 return(NULL);
799 line_read[500] = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000800 len = strlen(line_read);
801 ret = (char *) malloc(len + 1);
802 if (ret != NULL) {
803 memcpy (ret, line_read, len + 1);
804 }
805 return(ret);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000806#endif
807}
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000808#endif /* LIBXML_XPATH_ENABLED */
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000809#endif /* LIBXML_DEBUG_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000810
811/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +0200812 * *
813 * I/O Interfaces *
814 * *
Daniel Veillard5e873c42000-04-12 13:27:38 +0000815 ************************************************************************/
816
Nick Wellnhofer86615e42017-11-09 17:47:47 +0100817static int myRead(void *f, char *buf, int len) {
818 return(fread(buf, 1, len, (FILE *) f));
Daniel Veillard5e873c42000-04-12 13:27:38 +0000819}
Nick Wellnhofer86615e42017-11-09 17:47:47 +0100820static int myClose(void *context) {
821 FILE *f = (FILE *) context;
822 if (f == stdin)
823 return(0);
824 return(fclose(f));
Daniel Veillard5e873c42000-04-12 13:27:38 +0000825}
826
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000827/************************************************************************
828 * *
Daniel Veillardf1edb102009-08-10 14:43:18 +0200829 * SAX based tests *
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000830 * *
831 ************************************************************************/
832
833/*
834 * empty SAX block
835 */
Daniel Veillard24505b02005-07-28 23:49:35 +0000836static xmlSAXHandler emptySAXHandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000837 NULL, /* internalSubset */
838 NULL, /* isStandalone */
839 NULL, /* hasInternalSubset */
840 NULL, /* hasExternalSubset */
841 NULL, /* resolveEntity */
842 NULL, /* getEntity */
843 NULL, /* entityDecl */
844 NULL, /* notationDecl */
845 NULL, /* attributeDecl */
846 NULL, /* elementDecl */
847 NULL, /* unparsedEntityDecl */
848 NULL, /* setDocumentLocator */
849 NULL, /* startDocument */
850 NULL, /* endDocument */
851 NULL, /* startElement */
852 NULL, /* endElement */
853 NULL, /* reference */
854 NULL, /* characters */
855 NULL, /* ignorableWhitespace */
856 NULL, /* processingInstruction */
857 NULL, /* comment */
858 NULL, /* xmlParserWarning */
859 NULL, /* xmlParserError */
860 NULL, /* xmlParserError */
861 NULL, /* getParameterEntity */
862 NULL, /* cdataBlock; */
863 NULL, /* externalSubset; */
Daniel Veillard971771e2005-07-09 17:32:57 +0000864 XML_SAX2_MAGIC,
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000865 NULL,
866 NULL, /* startElementNs */
867 NULL, /* endElementNs */
868 NULL /* xmlStructuredErrorFunc */
869};
870
Daniel Veillard24505b02005-07-28 23:49:35 +0000871static xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000872extern xmlSAXHandlerPtr debugSAXHandler;
873static int callbacks;
874
875/**
876 * isStandaloneDebug:
877 * @ctxt: An XML parser context
878 *
879 * Is this document tagged standalone ?
880 *
881 * Returns 1 if true
882 */
883static int
884isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
885{
886 callbacks++;
887 if (noout)
888 return(0);
889 fprintf(stdout, "SAX.isStandalone()\n");
890 return(0);
891}
892
893/**
894 * hasInternalSubsetDebug:
895 * @ctxt: An XML parser context
896 *
897 * Does this document has an internal subset
898 *
899 * Returns 1 if true
900 */
901static int
902hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
903{
904 callbacks++;
905 if (noout)
906 return(0);
907 fprintf(stdout, "SAX.hasInternalSubset()\n");
908 return(0);
909}
910
911/**
912 * hasExternalSubsetDebug:
913 * @ctxt: An XML parser context
914 *
915 * Does this document has an external subset
916 *
917 * Returns 1 if true
918 */
919static int
920hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
921{
922 callbacks++;
923 if (noout)
924 return(0);
925 fprintf(stdout, "SAX.hasExternalSubset()\n");
926 return(0);
927}
928
929/**
930 * internalSubsetDebug:
931 * @ctxt: An XML parser context
932 *
933 * Does this document has an internal subset
934 */
935static void
936internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
937 const xmlChar *ExternalID, const xmlChar *SystemID)
938{
939 callbacks++;
940 if (noout)
941 return;
942 fprintf(stdout, "SAX.internalSubset(%s,", name);
943 if (ExternalID == NULL)
944 fprintf(stdout, " ,");
945 else
946 fprintf(stdout, " %s,", ExternalID);
947 if (SystemID == NULL)
948 fprintf(stdout, " )\n");
949 else
950 fprintf(stdout, " %s)\n", SystemID);
951}
952
953/**
954 * externalSubsetDebug:
955 * @ctxt: An XML parser context
956 *
957 * Does this document has an external subset
958 */
959static void
960externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
961 const xmlChar *ExternalID, const xmlChar *SystemID)
962{
963 callbacks++;
964 if (noout)
965 return;
966 fprintf(stdout, "SAX.externalSubset(%s,", name);
967 if (ExternalID == NULL)
968 fprintf(stdout, " ,");
969 else
970 fprintf(stdout, " %s,", ExternalID);
971 if (SystemID == NULL)
972 fprintf(stdout, " )\n");
973 else
974 fprintf(stdout, " %s)\n", SystemID);
975}
976
977/**
978 * resolveEntityDebug:
979 * @ctxt: An XML parser context
980 * @publicId: The public ID of the entity
981 * @systemId: The system ID of the entity
982 *
983 * Special entity resolver, better left to the parser, it has
984 * more context than the application layer.
985 * The default behaviour is to NOT resolve the entities, in that case
986 * the ENTITY_REF nodes are built in the structure (and the parameter
987 * values).
988 *
989 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
990 */
991static xmlParserInputPtr
992resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
993{
994 callbacks++;
995 if (noout)
996 return(NULL);
997 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
998
Daniel Veillardf1edb102009-08-10 14:43:18 +0200999
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001000 fprintf(stdout, "SAX.resolveEntity(");
1001 if (publicId != NULL)
1002 fprintf(stdout, "%s", (char *)publicId);
1003 else
1004 fprintf(stdout, " ");
1005 if (systemId != NULL)
1006 fprintf(stdout, ", %s)\n", (char *)systemId);
1007 else
1008 fprintf(stdout, ", )\n");
1009 return(NULL);
1010}
1011
1012/**
1013 * getEntityDebug:
1014 * @ctxt: An XML parser context
1015 * @name: The entity name
1016 *
1017 * Get an entity by name
1018 *
1019 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
1020 */
1021static xmlEntityPtr
1022getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1023{
1024 callbacks++;
1025 if (noout)
1026 return(NULL);
1027 fprintf(stdout, "SAX.getEntity(%s)\n", name);
1028 return(NULL);
1029}
1030
1031/**
1032 * getParameterEntityDebug:
1033 * @ctxt: An XML parser context
1034 * @name: The entity name
1035 *
1036 * Get a parameter entity by name
1037 *
1038 * Returns the xmlParserInputPtr
1039 */
1040static xmlEntityPtr
1041getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1042{
1043 callbacks++;
1044 if (noout)
1045 return(NULL);
1046 fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
1047 return(NULL);
1048}
1049
1050
1051/**
1052 * entityDeclDebug:
1053 * @ctxt: An XML parser context
Daniel Veillardf1edb102009-08-10 14:43:18 +02001054 * @name: the entity name
1055 * @type: the entity type
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001056 * @publicId: The public ID of the entity
1057 * @systemId: The system ID of the entity
1058 * @content: the entity value (without processing).
1059 *
1060 * An entity definition has been parsed
1061 */
1062static void
1063entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
1064 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
1065{
1066const xmlChar *nullstr = BAD_CAST "(null)";
1067 /* not all libraries handle printing null pointers nicely */
1068 if (publicId == NULL)
1069 publicId = nullstr;
1070 if (systemId == NULL)
1071 systemId = nullstr;
1072 if (content == NULL)
1073 content = (xmlChar *)nullstr;
1074 callbacks++;
1075 if (noout)
1076 return;
1077 fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
1078 name, type, publicId, systemId, content);
1079}
1080
1081/**
1082 * attributeDeclDebug:
1083 * @ctxt: An XML parser context
Daniel Veillardf1edb102009-08-10 14:43:18 +02001084 * @name: the attribute name
1085 * @type: the attribute type
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001086 *
1087 * An attribute definition has been parsed
1088 */
1089static void
1090attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar * elem,
1091 const xmlChar * name, int type, int def,
1092 const xmlChar * defaultValue, xmlEnumerationPtr tree)
1093{
1094 callbacks++;
1095 if (noout)
1096 return;
1097 if (defaultValue == NULL)
1098 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
1099 elem, name, type, def);
1100 else
1101 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
1102 elem, name, type, def, defaultValue);
1103 xmlFreeEnumeration(tree);
1104}
1105
1106/**
1107 * elementDeclDebug:
1108 * @ctxt: An XML parser context
Daniel Veillardf1edb102009-08-10 14:43:18 +02001109 * @name: the element name
1110 * @type: the element type
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001111 * @content: the element value (without processing).
1112 *
1113 * An element definition has been parsed
1114 */
1115static void
1116elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
1117 xmlElementContentPtr content ATTRIBUTE_UNUSED)
1118{
1119 callbacks++;
1120 if (noout)
1121 return;
1122 fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
1123 name, type);
1124}
1125
1126/**
1127 * notationDeclDebug:
1128 * @ctxt: An XML parser context
1129 * @name: The name of the notation
1130 * @publicId: The public ID of the entity
1131 * @systemId: The system ID of the entity
1132 *
1133 * What to do when a notation declaration has been parsed.
1134 */
1135static void
1136notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
1137 const xmlChar *publicId, const xmlChar *systemId)
1138{
1139 callbacks++;
1140 if (noout)
1141 return;
1142 fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
1143 (char *) name, (char *) publicId, (char *) systemId);
1144}
1145
1146/**
1147 * unparsedEntityDeclDebug:
1148 * @ctxt: An XML parser context
1149 * @name: The name of the entity
1150 * @publicId: The public ID of the entity
1151 * @systemId: The system ID of the entity
1152 * @notationName: the name of the notation
1153 *
1154 * What to do when an unparsed entity declaration is parsed
1155 */
1156static void
1157unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
1158 const xmlChar *publicId, const xmlChar *systemId,
1159 const xmlChar *notationName)
1160{
1161const xmlChar *nullstr = BAD_CAST "(null)";
1162
1163 if (publicId == NULL)
1164 publicId = nullstr;
1165 if (systemId == NULL)
1166 systemId = nullstr;
1167 if (notationName == NULL)
1168 notationName = nullstr;
1169 callbacks++;
1170 if (noout)
1171 return;
1172 fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
1173 (char *) name, (char *) publicId, (char *) systemId,
1174 (char *) notationName);
1175}
1176
1177/**
1178 * setDocumentLocatorDebug:
1179 * @ctxt: An XML parser context
1180 * @loc: A SAX Locator
1181 *
1182 * Receive the document locator at startup, actually xmlDefaultSAXLocator
1183 * Everything is available on the context, so this is useless in our case.
1184 */
1185static void
1186setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
1187{
1188 callbacks++;
1189 if (noout)
1190 return;
1191 fprintf(stdout, "SAX.setDocumentLocator()\n");
1192}
1193
1194/**
1195 * startDocumentDebug:
1196 * @ctxt: An XML parser context
1197 *
1198 * called when the document start being processed.
1199 */
1200static void
1201startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
1202{
1203 callbacks++;
1204 if (noout)
1205 return;
1206 fprintf(stdout, "SAX.startDocument()\n");
1207}
1208
1209/**
1210 * endDocumentDebug:
1211 * @ctxt: An XML parser context
1212 *
1213 * called when the document end has been detected.
1214 */
1215static void
1216endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
1217{
1218 callbacks++;
1219 if (noout)
1220 return;
1221 fprintf(stdout, "SAX.endDocument()\n");
1222}
1223
1224/**
1225 * startElementDebug:
1226 * @ctxt: An XML parser context
1227 * @name: The element name
1228 *
1229 * called when an opening tag has been processed.
1230 */
1231static void
1232startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
1233{
1234 int i;
1235
1236 callbacks++;
1237 if (noout)
1238 return;
1239 fprintf(stdout, "SAX.startElement(%s", (char *) name);
1240 if (atts != NULL) {
1241 for (i = 0;(atts[i] != NULL);i++) {
1242 fprintf(stdout, ", %s='", atts[i++]);
1243 if (atts[i] != NULL)
1244 fprintf(stdout, "%s'", atts[i]);
1245 }
1246 }
1247 fprintf(stdout, ")\n");
1248}
1249
1250/**
1251 * endElementDebug:
1252 * @ctxt: An XML parser context
1253 * @name: The element name
1254 *
1255 * called when the end of an element has been detected.
1256 */
1257static void
1258endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1259{
1260 callbacks++;
1261 if (noout)
1262 return;
1263 fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
1264}
1265
1266/**
1267 * charactersDebug:
1268 * @ctxt: An XML parser context
1269 * @ch: a xmlChar string
1270 * @len: the number of xmlChar
1271 *
1272 * receiving some chars from the parser.
1273 * Question: how much at a time ???
1274 */
1275static void
1276charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
1277{
1278 char out[40];
1279 int i;
1280
1281 callbacks++;
1282 if (noout)
1283 return;
1284 for (i = 0;(i<len) && (i < 30);i++)
1285 out[i] = ch[i];
1286 out[i] = 0;
1287
1288 fprintf(stdout, "SAX.characters(%s, %d)\n", out, len);
1289}
1290
1291/**
1292 * referenceDebug:
1293 * @ctxt: An XML parser context
1294 * @name: The entity name
1295 *
Daniel Veillardf1edb102009-08-10 14:43:18 +02001296 * called when an entity reference is detected.
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001297 */
1298static void
1299referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1300{
1301 callbacks++;
1302 if (noout)
1303 return;
1304 fprintf(stdout, "SAX.reference(%s)\n", name);
1305}
1306
1307/**
1308 * ignorableWhitespaceDebug:
1309 * @ctxt: An XML parser context
1310 * @ch: a xmlChar string
1311 * @start: the first char in the string
1312 * @len: the number of xmlChar
1313 *
1314 * receiving some ignorable whitespaces from the parser.
1315 * Question: how much at a time ???
1316 */
1317static void
1318ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
1319{
1320 char out[40];
1321 int i;
1322
1323 callbacks++;
1324 if (noout)
1325 return;
1326 for (i = 0;(i<len) && (i < 30);i++)
1327 out[i] = ch[i];
1328 out[i] = 0;
1329 fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", out, len);
1330}
1331
1332/**
1333 * processingInstructionDebug:
1334 * @ctxt: An XML parser context
1335 * @target: the target name
1336 * @data: the PI data's
1337 * @len: the number of xmlChar
1338 *
1339 * A processing instruction has been parsed.
1340 */
1341static void
1342processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
1343 const xmlChar *data)
1344{
1345 callbacks++;
1346 if (noout)
1347 return;
1348 if (data != NULL)
1349 fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
1350 (char *) target, (char *) data);
1351 else
1352 fprintf(stdout, "SAX.processingInstruction(%s, NULL)\n",
1353 (char *) target);
1354}
1355
1356/**
1357 * cdataBlockDebug:
1358 * @ctx: the user data (XML parser context)
1359 * @value: The pcdata content
1360 * @len: the block length
1361 *
1362 * called when a pcdata block has been parsed
1363 */
1364static void
1365cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
1366{
1367 callbacks++;
1368 if (noout)
1369 return;
1370 fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
1371 (char *) value, len);
1372}
1373
1374/**
1375 * commentDebug:
1376 * @ctxt: An XML parser context
1377 * @value: the comment content
1378 *
1379 * A comment has been parsed.
1380 */
1381static void
1382commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
1383{
1384 callbacks++;
1385 if (noout)
1386 return;
1387 fprintf(stdout, "SAX.comment(%s)\n", value);
1388}
1389
1390/**
1391 * warningDebug:
1392 * @ctxt: An XML parser context
1393 * @msg: the message to display/transmit
1394 * @...: extra parameters for the message display
1395 *
1396 * Display and format a warning messages, gives file, line, position and
1397 * extra parameters.
1398 */
David Kilzer4472c3a2016-05-13 15:13:17 +08001399static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001400warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1401{
1402 va_list args;
1403
1404 callbacks++;
1405 if (noout)
1406 return;
1407 va_start(args, msg);
1408 fprintf(stdout, "SAX.warning: ");
1409 vfprintf(stdout, msg, args);
1410 va_end(args);
1411}
1412
1413/**
1414 * errorDebug:
1415 * @ctxt: An XML parser context
1416 * @msg: the message to display/transmit
1417 * @...: extra parameters for the message display
1418 *
1419 * Display and format a error messages, gives file, line, position and
1420 * extra parameters.
1421 */
David Kilzer4472c3a2016-05-13 15:13:17 +08001422static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001423errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1424{
1425 va_list args;
1426
1427 callbacks++;
1428 if (noout)
1429 return;
1430 va_start(args, msg);
1431 fprintf(stdout, "SAX.error: ");
1432 vfprintf(stdout, msg, args);
1433 va_end(args);
1434}
1435
1436/**
1437 * fatalErrorDebug:
1438 * @ctxt: An XML parser context
1439 * @msg: the message to display/transmit
1440 * @...: extra parameters for the message display
1441 *
1442 * Display and format a fatalError messages, gives file, line, position and
1443 * extra parameters.
1444 */
David Kilzer4472c3a2016-05-13 15:13:17 +08001445static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001446fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1447{
1448 va_list args;
1449
1450 callbacks++;
1451 if (noout)
1452 return;
1453 va_start(args, msg);
1454 fprintf(stdout, "SAX.fatalError: ");
1455 vfprintf(stdout, msg, args);
1456 va_end(args);
1457}
1458
Daniel Veillard24505b02005-07-28 23:49:35 +00001459static xmlSAXHandler debugSAXHandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001460 internalSubsetDebug,
1461 isStandaloneDebug,
1462 hasInternalSubsetDebug,
1463 hasExternalSubsetDebug,
1464 resolveEntityDebug,
1465 getEntityDebug,
1466 entityDeclDebug,
1467 notationDeclDebug,
1468 attributeDeclDebug,
1469 elementDeclDebug,
1470 unparsedEntityDeclDebug,
1471 setDocumentLocatorDebug,
1472 startDocumentDebug,
1473 endDocumentDebug,
1474 startElementDebug,
1475 endElementDebug,
1476 referenceDebug,
1477 charactersDebug,
1478 ignorableWhitespaceDebug,
1479 processingInstructionDebug,
1480 commentDebug,
1481 warningDebug,
1482 errorDebug,
1483 fatalErrorDebug,
1484 getParameterEntityDebug,
1485 cdataBlockDebug,
1486 externalSubsetDebug,
1487 1,
1488 NULL,
1489 NULL,
1490 NULL,
1491 NULL
1492};
1493
1494xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
1495
1496/*
1497 * SAX2 specific callbacks
1498 */
1499/**
1500 * startElementNsDebug:
1501 * @ctxt: An XML parser context
1502 * @name: The element name
1503 *
1504 * called when an opening tag has been processed.
1505 */
1506static void
1507startElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
1508 const xmlChar *localname,
1509 const xmlChar *prefix,
1510 const xmlChar *URI,
1511 int nb_namespaces,
1512 const xmlChar **namespaces,
1513 int nb_attributes,
1514 int nb_defaulted,
1515 const xmlChar **attributes)
1516{
1517 int i;
1518
1519 callbacks++;
1520 if (noout)
1521 return;
1522 fprintf(stdout, "SAX.startElementNs(%s", (char *) localname);
1523 if (prefix == NULL)
1524 fprintf(stdout, ", NULL");
1525 else
1526 fprintf(stdout, ", %s", (char *) prefix);
1527 if (URI == NULL)
1528 fprintf(stdout, ", NULL");
1529 else
1530 fprintf(stdout, ", '%s'", (char *) URI);
1531 fprintf(stdout, ", %d", nb_namespaces);
Daniel Veillardf1edb102009-08-10 14:43:18 +02001532
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001533 if (namespaces != NULL) {
1534 for (i = 0;i < nb_namespaces * 2;i++) {
1535 fprintf(stdout, ", xmlns");
1536 if (namespaces[i] != NULL)
1537 fprintf(stdout, ":%s", namespaces[i]);
1538 i++;
1539 fprintf(stdout, "='%s'", namespaces[i]);
1540 }
1541 }
1542 fprintf(stdout, ", %d, %d", nb_attributes, nb_defaulted);
1543 if (attributes != NULL) {
1544 for (i = 0;i < nb_attributes * 5;i += 5) {
1545 if (attributes[i + 1] != NULL)
1546 fprintf(stdout, ", %s:%s='", attributes[i + 1], attributes[i]);
1547 else
1548 fprintf(stdout, ", %s='", attributes[i]);
1549 fprintf(stdout, "%.4s...', %d", attributes[i + 3],
1550 (int)(attributes[i + 4] - attributes[i + 3]));
1551 }
1552 }
1553 fprintf(stdout, ")\n");
1554}
1555
1556/**
1557 * endElementDebug:
1558 * @ctxt: An XML parser context
1559 * @name: The element name
1560 *
1561 * called when the end of an element has been detected.
1562 */
1563static void
1564endElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
1565 const xmlChar *localname,
1566 const xmlChar *prefix,
1567 const xmlChar *URI)
1568{
1569 callbacks++;
1570 if (noout)
1571 return;
1572 fprintf(stdout, "SAX.endElementNs(%s", (char *) localname);
1573 if (prefix == NULL)
1574 fprintf(stdout, ", NULL");
1575 else
1576 fprintf(stdout, ", %s", (char *) prefix);
1577 if (URI == NULL)
1578 fprintf(stdout, ", NULL)\n");
1579 else
1580 fprintf(stdout, ", '%s')\n", (char *) URI);
1581}
1582
Daniel Veillard24505b02005-07-28 23:49:35 +00001583static xmlSAXHandler debugSAX2HandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001584 internalSubsetDebug,
1585 isStandaloneDebug,
1586 hasInternalSubsetDebug,
1587 hasExternalSubsetDebug,
1588 resolveEntityDebug,
1589 getEntityDebug,
1590 entityDeclDebug,
1591 notationDeclDebug,
1592 attributeDeclDebug,
1593 elementDeclDebug,
1594 unparsedEntityDeclDebug,
1595 setDocumentLocatorDebug,
1596 startDocumentDebug,
1597 endDocumentDebug,
1598 NULL,
1599 NULL,
1600 referenceDebug,
1601 charactersDebug,
1602 ignorableWhitespaceDebug,
1603 processingInstructionDebug,
1604 commentDebug,
1605 warningDebug,
1606 errorDebug,
1607 fatalErrorDebug,
1608 getParameterEntityDebug,
1609 cdataBlockDebug,
1610 externalSubsetDebug,
1611 XML_SAX2_MAGIC,
1612 NULL,
1613 startElementNsDebug,
1614 endElementNsDebug,
1615 NULL
1616};
1617
Daniel Veillard24505b02005-07-28 23:49:35 +00001618static xmlSAXHandlerPtr debugSAX2Handler = &debugSAX2HandlerStruct;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001619
1620static void
1621testSAX(const char *filename) {
1622 xmlSAXHandlerPtr handler;
1623 const char *user_data = "user_data"; /* mostly for debugging */
1624 xmlParserInputBufferPtr buf = NULL;
1625 xmlParserInputPtr inputStream;
1626 xmlParserCtxtPtr ctxt = NULL;
1627 xmlSAXHandlerPtr old_sax = NULL;
1628
1629 callbacks = 0;
1630
1631 if (noout) {
1632 handler = emptySAXHandler;
Daniel Veillard78dfc9f2005-07-10 22:30:30 +00001633#ifdef LIBXML_SAX1_ENABLED
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001634 } else if (sax1) {
1635 handler = debugSAXHandler;
Daniel Veillard78dfc9f2005-07-10 22:30:30 +00001636#endif
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001637 } else {
1638 handler = debugSAX2Handler;
1639 }
1640
1641 /*
1642 * it's not the simplest code but the most generic in term of I/O
1643 */
1644 buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
1645 if (buf == NULL) {
1646 goto error;
1647 }
1648
1649#ifdef LIBXML_SCHEMAS_ENABLED
1650 if (wxschemas != NULL) {
1651 int ret;
1652 xmlSchemaValidCtxtPtr vctxt;
1653
1654 vctxt = xmlSchemaNewValidCtxt(wxschemas);
1655 xmlSchemaSetValidErrors(vctxt,
1656 (xmlSchemaValidityErrorFunc) fprintf,
1657 (xmlSchemaValidityWarningFunc) fprintf,
1658 stderr);
Daniel Veillard97fa5b32012-08-14 11:01:07 +08001659 xmlSchemaValidateSetFilename(vctxt, filename);
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001660
Daniel Veillard971771e2005-07-09 17:32:57 +00001661 ret = xmlSchemaValidateStream(vctxt, buf, 0, handler,
1662 (void *)user_data);
1663 if (repeat == 0) {
1664 if (ret == 0) {
1665 fprintf(stderr, "%s validates\n", filename);
1666 } else if (ret > 0) {
1667 fprintf(stderr, "%s fails to validate\n", filename);
1668 progresult = XMLLINT_ERR_VALID;
1669 } else {
1670 fprintf(stderr, "%s validation generated an internal error\n",
1671 filename);
1672 progresult = XMLLINT_ERR_VALID;
1673 }
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001674 }
1675 xmlSchemaFreeValidCtxt(vctxt);
1676 } else
1677#endif
1678 {
1679 /*
1680 * Create the parser context amd hook the input
1681 */
1682 ctxt = xmlNewParserCtxt();
1683 if (ctxt == NULL) {
1684 xmlFreeParserInputBuffer(buf);
1685 goto error;
1686 }
1687 old_sax = ctxt->sax;
1688 ctxt->sax = handler;
1689 ctxt->userData = (void *) user_data;
1690 inputStream = xmlNewIOInputStream(ctxt, buf, XML_CHAR_ENCODING_NONE);
1691 if (inputStream == NULL) {
1692 xmlFreeParserInputBuffer(buf);
1693 goto error;
1694 }
1695 inputPush(ctxt, inputStream);
Daniel Veillardf1edb102009-08-10 14:43:18 +02001696
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001697 /* do the parsing */
1698 xmlParseDocument(ctxt);
1699
1700 if (ctxt->myDoc != NULL) {
1701 fprintf(stderr, "SAX generated a doc !\n");
1702 xmlFreeDoc(ctxt->myDoc);
1703 ctxt->myDoc = NULL;
1704 }
1705 }
1706
1707error:
1708 if (ctxt != NULL) {
1709 ctxt->sax = old_sax;
1710 xmlFreeParserCtxt(ctxt);
1711 }
1712}
1713
Daniel Veillard5e873c42000-04-12 13:27:38 +00001714/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +02001715 * *
1716 * Stream Test processing *
1717 * *
Daniel Veillard7704fb12003-01-03 16:19:51 +00001718 ************************************************************************/
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001719#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00001720static void processNode(xmlTextReaderPtr reader) {
Daniel Veillard198c1bf2003-10-20 17:07:41 +00001721 const xmlChar *name, *value;
Daniel Veillard16ef8002005-01-31 00:27:50 +00001722 int type, empty;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001723
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001724 type = xmlTextReaderNodeType(reader);
Daniel Veillard16ef8002005-01-31 00:27:50 +00001725 empty = xmlTextReaderIsEmptyElement(reader);
Daniel Veillard99737f52003-03-22 14:55:50 +00001726
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001727 if (debug) {
1728 name = xmlTextReaderConstName(reader);
1729 if (name == NULL)
1730 name = BAD_CAST "--";
Daniel Veillard7704fb12003-01-03 16:19:51 +00001731
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001732 value = xmlTextReaderConstValue(reader);
1733
Daniel Veillardf1edb102009-08-10 14:43:18 +02001734
1735 printf("%d %d %s %d %d",
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001736 xmlTextReaderDepth(reader),
1737 type,
1738 name,
Daniel Veillard16ef8002005-01-31 00:27:50 +00001739 empty,
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001740 xmlTextReaderHasValue(reader));
1741 if (value == NULL)
1742 printf("\n");
1743 else {
1744 printf(" %s\n", value);
1745 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001746 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001747#ifdef LIBXML_PATTERN_ENABLED
1748 if (patternc) {
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001749 xmlChar *path = NULL;
1750 int match = -1;
Daniel Veillardf1edb102009-08-10 14:43:18 +02001751
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001752 if (type == XML_READER_TYPE_ELEMENT) {
1753 /* do the check only on element start */
1754 match = xmlPatternMatch(patternc, xmlTextReaderCurrentNode(reader));
1755
1756 if (match) {
Daniel Veillardf1edb102009-08-10 14:43:18 +02001757#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001758 path = xmlGetNodePath(xmlTextReaderCurrentNode(reader));
1759 printf("Node %s matches pattern %s\n", path, pattern);
Daniel Veillardf1edb102009-08-10 14:43:18 +02001760#else
1761 printf("Node %s matches pattern %s\n",
1762 xmlTextReaderConstName(reader), pattern);
1763#endif
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001764 }
1765 }
1766 if (patstream != NULL) {
1767 int ret;
1768
1769 if (type == XML_READER_TYPE_ELEMENT) {
1770 ret = xmlStreamPush(patstream,
1771 xmlTextReaderConstLocalName(reader),
1772 xmlTextReaderConstNamespaceUri(reader));
1773 if (ret < 0) {
1774 fprintf(stderr, "xmlStreamPush() failure\n");
1775 xmlFreeStreamCtxt(patstream);
1776 patstream = NULL;
1777 } else if (ret != match) {
Daniel Veillardf1edb102009-08-10 14:43:18 +02001778#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001779 if (path == NULL) {
1780 path = xmlGetNodePath(
1781 xmlTextReaderCurrentNode(reader));
1782 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02001783#endif
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001784 fprintf(stderr,
1785 "xmlPatternMatch and xmlStreamPush disagree\n");
Daniel Veillardf1edb102009-08-10 14:43:18 +02001786 if (path != NULL)
1787 fprintf(stderr, " pattern %s node %s\n",
1788 pattern, path);
1789 else
1790 fprintf(stderr, " pattern %s node %s\n",
1791 pattern, xmlTextReaderConstName(reader));
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001792 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001793
Daniel Veillardf1edb102009-08-10 14:43:18 +02001794 }
Daniel Veillard16ef8002005-01-31 00:27:50 +00001795 if ((type == XML_READER_TYPE_END_ELEMENT) ||
1796 ((type == XML_READER_TYPE_ELEMENT) && (empty))) {
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001797 ret = xmlStreamPop(patstream);
1798 if (ret < 0) {
1799 fprintf(stderr, "xmlStreamPop() failure\n");
1800 xmlFreeStreamCtxt(patstream);
1801 patstream = NULL;
1802 }
1803 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001804 }
Daniel Veillardf9d16912005-01-30 22:36:30 +00001805 if (path != NULL)
1806 xmlFree(path);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001807 }
1808#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001809}
1810
1811static void streamFile(char *filename) {
1812 xmlTextReaderPtr reader;
1813 int ret;
Daniel Richard G5706b6d2012-08-06 11:32:54 +08001814#ifdef HAVE_MMAP
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001815 int fd = -1;
1816 struct stat info;
1817 const char *base = NULL;
1818 xmlParserInputBufferPtr input = NULL;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001819
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001820 if (memory) {
Daniel Veillardf1edb102009-08-10 14:43:18 +02001821 if (stat(filename, &info) < 0)
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001822 return;
1823 if ((fd = open(filename, O_RDONLY)) < 0)
1824 return;
1825 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillardb98c6a02013-07-12 12:08:40 +08001826 if (base == (void *) MAP_FAILED) {
1827 close(fd);
1828 fprintf(stderr, "mmap failure for file %s\n", filename);
1829 progresult = XMLLINT_ERR_RDFILE;
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001830 return;
Daniel Veillardb98c6a02013-07-12 12:08:40 +08001831 }
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001832
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001833 reader = xmlReaderForMemory(base, info.st_size, filename,
1834 NULL, options);
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001835 } else
1836#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001837 reader = xmlReaderForFile(filename, NULL, options);
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001838#ifdef LIBXML_PATTERN_ENABLED
Daniel Veillardd4301ab2005-02-03 22:24:10 +00001839 if (pattern != NULL) {
1840 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
1841 if (patternc == NULL) {
1842 xmlGenericError(xmlGenericErrorContext,
1843 "Pattern %s failed to compile\n", pattern);
1844 progresult = XMLLINT_ERR_SCHEMAPAT;
1845 pattern = NULL;
1846 }
1847 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001848 if (patternc != NULL) {
1849 patstream = xmlPatternGetStreamCtxt(patternc);
1850 if (patstream != NULL) {
1851 ret = xmlStreamPush(patstream, NULL, NULL);
1852 if (ret < 0) {
1853 fprintf(stderr, "xmlStreamPush() failure\n");
1854 xmlFreeStreamCtxt(patstream);
1855 patstream = NULL;
1856 }
1857 }
1858 }
1859#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001860
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001861
Daniel Veillard7704fb12003-01-03 16:19:51 +00001862 if (reader != NULL) {
Daniel Veillard4432df22003-09-28 18:58:27 +00001863#ifdef LIBXML_VALID_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00001864 if (valid)
1865 xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
Daniel Veillardce192eb2003-04-16 15:58:05 +00001866 else
Daniel Veillard4432df22003-09-28 18:58:27 +00001867#endif /* LIBXML_VALID_ENABLED */
Daniel Veillarde4d16d72012-12-21 10:58:14 +08001868 if (loaddtd)
1869 xmlTextReaderSetParserProp(reader, XML_PARSER_LOADDTD, 1);
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001870#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +00001871 if (relaxng != NULL) {
Daniel Veillard81514ba2003-09-16 23:17:26 +00001872 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001873 startTimer();
1874 }
1875 ret = xmlTextReaderRelaxNGValidate(reader, relaxng);
1876 if (ret < 0) {
1877 xmlGenericError(xmlGenericErrorContext,
1878 "Relax-NG schema %s failed to compile\n", relaxng);
William M. Brack8304d872004-06-08 13:29:32 +00001879 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillardce192eb2003-04-16 15:58:05 +00001880 relaxng = NULL;
1881 }
Daniel Veillard81514ba2003-09-16 23:17:26 +00001882 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001883 endTimer("Compiling the schemas");
1884 }
1885 }
Daniel Veillardf10ae122005-07-10 19:03:16 +00001886 if (schema != NULL) {
1887 if ((timing) && (!repeat)) {
1888 startTimer();
1889 }
1890 ret = xmlTextReaderSchemaValidate(reader, schema);
1891 if (ret < 0) {
1892 xmlGenericError(xmlGenericErrorContext,
1893 "XSD schema %s failed to compile\n", schema);
1894 progresult = XMLLINT_ERR_SCHEMACOMP;
1895 schema = NULL;
1896 }
1897 if ((timing) && (!repeat)) {
1898 endTimer("Compiling the schemas");
1899 }
1900 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001901#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001902
1903 /*
1904 * Process all nodes in sequence
1905 */
Daniel Veillard81514ba2003-09-16 23:17:26 +00001906 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001907 startTimer();
1908 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001909 ret = xmlTextReaderRead(reader);
1910 while (ret == 1) {
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001911 if ((debug)
1912#ifdef LIBXML_PATTERN_ENABLED
1913 || (patternc)
1914#endif
1915 )
Daniel Veillard7704fb12003-01-03 16:19:51 +00001916 processNode(reader);
1917 ret = xmlTextReaderRead(reader);
1918 }
Daniel Veillard81514ba2003-09-16 23:17:26 +00001919 if ((timing) && (!repeat)) {
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001920#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf54cd532004-02-25 11:52:31 +00001921 if (relaxng != NULL)
Daniel Veillard49138f12004-02-19 12:58:36 +00001922 endTimer("Parsing and validating");
1923 else
Daniel Veillardf54cd532004-02-25 11:52:31 +00001924#endif
Daniel Veillard4432df22003-09-28 18:58:27 +00001925#ifdef LIBXML_VALID_ENABLED
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001926 if (valid)
Daniel Veillardce192eb2003-04-16 15:58:05 +00001927 endTimer("Parsing and validating");
1928 else
Daniel Veillard4432df22003-09-28 18:58:27 +00001929#endif
Daniel Veillardf54cd532004-02-25 11:52:31 +00001930 endTimer("Parsing");
Daniel Veillardce192eb2003-04-16 15:58:05 +00001931 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001932
Daniel Veillard4432df22003-09-28 18:58:27 +00001933#ifdef LIBXML_VALID_ENABLED
Daniel Veillardf6bad792003-04-11 19:38:54 +00001934 if (valid) {
1935 if (xmlTextReaderIsValid(reader) != 1) {
1936 xmlGenericError(xmlGenericErrorContext,
1937 "Document %s does not validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001938 progresult = XMLLINT_ERR_VALID;
Daniel Veillardf6bad792003-04-11 19:38:54 +00001939 }
1940 }
Daniel Veillard4432df22003-09-28 18:58:27 +00001941#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001942#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf10ae122005-07-10 19:03:16 +00001943 if ((relaxng != NULL) || (schema != NULL)) {
Daniel Veillardf4e55762003-04-15 23:32:22 +00001944 if (xmlTextReaderIsValid(reader) != 1) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001945 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001946 progresult = XMLLINT_ERR_VALID;
Daniel Veillardf4e55762003-04-15 23:32:22 +00001947 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001948 fprintf(stderr, "%s validates\n", filename);
Daniel Veillardf4e55762003-04-15 23:32:22 +00001949 }
1950 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001951#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001952 /*
1953 * Done, cleanup and status
1954 */
1955 xmlFreeTextReader(reader);
1956 if (ret != 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001957 fprintf(stderr, "%s : failed to parse\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001958 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001959 }
1960 } else {
1961 fprintf(stderr, "Unable to open %s\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001962 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001963 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001964#ifdef LIBXML_PATTERN_ENABLED
1965 if (patstream != NULL) {
1966 xmlFreeStreamCtxt(patstream);
1967 patstream = NULL;
1968 }
1969#endif
Daniel Richard G5706b6d2012-08-06 11:32:54 +08001970#ifdef HAVE_MMAP
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001971 if (memory) {
1972 xmlFreeParserInputBuffer(input);
1973 munmap((char *) base, info.st_size);
1974 close(fd);
1975 }
1976#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001977}
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001978
1979static void walkDoc(xmlDocPtr doc) {
1980 xmlTextReaderPtr reader;
1981 int ret;
1982
Daniel Veillardd4301ab2005-02-03 22:24:10 +00001983#ifdef LIBXML_PATTERN_ENABLED
1984 xmlNodePtr root;
1985 const xmlChar *namespaces[22];
1986 int i;
1987 xmlNsPtr ns;
1988
1989 root = xmlDocGetRootElement(doc);
Hugh Davenportb8e0fa32016-05-04 10:55:49 +08001990 if (root == NULL ) {
1991 xmlGenericError(xmlGenericErrorContext,
1992 "Document does not have a root element");
1993 progresult = XMLLINT_ERR_UNCLASS;
1994 return;
1995 }
Daniel Veillardd4301ab2005-02-03 22:24:10 +00001996 for (ns = root->nsDef, i = 0;ns != NULL && i < 20;ns=ns->next) {
1997 namespaces[i++] = ns->href;
1998 namespaces[i++] = ns->prefix;
1999 }
2000 namespaces[i++] = NULL;
Daniel Veillard13cee4e2009-09-05 14:52:55 +02002001 namespaces[i] = NULL;
Daniel Veillardd4301ab2005-02-03 22:24:10 +00002002
2003 if (pattern != NULL) {
2004 patternc = xmlPatterncompile((const xmlChar *) pattern, doc->dict,
2005 0, &namespaces[0]);
2006 if (patternc == NULL) {
2007 xmlGenericError(xmlGenericErrorContext,
2008 "Pattern %s failed to compile\n", pattern);
2009 progresult = XMLLINT_ERR_SCHEMAPAT;
2010 pattern = NULL;
2011 }
2012 }
Daniel Veillard2b2e02d2005-02-05 23:20:22 +00002013 if (patternc != NULL) {
2014 patstream = xmlPatternGetStreamCtxt(patternc);
2015 if (patstream != NULL) {
2016 ret = xmlStreamPush(patstream, NULL, NULL);
2017 if (ret < 0) {
2018 fprintf(stderr, "xmlStreamPush() failure\n");
2019 xmlFreeStreamCtxt(patstream);
2020 patstream = NULL;
2021 }
2022 }
2023 }
Daniel Veillardd4301ab2005-02-03 22:24:10 +00002024#endif /* LIBXML_PATTERN_ENABLED */
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002025 reader = xmlReaderWalker(doc);
2026 if (reader != NULL) {
2027 if ((timing) && (!repeat)) {
2028 startTimer();
2029 }
2030 ret = xmlTextReaderRead(reader);
2031 while (ret == 1) {
Daniel Veillardb3de70c2003-12-02 22:32:15 +00002032 if ((debug)
2033#ifdef LIBXML_PATTERN_ENABLED
2034 || (patternc)
2035#endif
2036 )
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002037 processNode(reader);
2038 ret = xmlTextReaderRead(reader);
2039 }
2040 if ((timing) && (!repeat)) {
2041 endTimer("walking through the doc");
2042 }
2043 xmlFreeTextReader(reader);
2044 if (ret != 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002045 fprintf(stderr, "failed to walk through the doc\n");
William M. Brack8304d872004-06-08 13:29:32 +00002046 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002047 }
2048 } else {
2049 fprintf(stderr, "Failed to crate a reader from the document\n");
William M. Brack8304d872004-06-08 13:29:32 +00002050 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002051 }
Daniel Veillard2b2e02d2005-02-05 23:20:22 +00002052#ifdef LIBXML_PATTERN_ENABLED
2053 if (patstream != NULL) {
2054 xmlFreeStreamCtxt(patstream);
2055 patstream = NULL;
2056 }
2057#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002058}
Daniel Veillard81273902003-09-30 00:43:48 +00002059#endif /* LIBXML_READER_ENABLED */
Daniel Veillard7704fb12003-01-03 16:19:51 +00002060
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002061#ifdef LIBXML_XPATH_ENABLED
2062/************************************************************************
2063 * *
2064 * XPath Query *
2065 * *
2066 ************************************************************************/
2067
2068static void doXPathDump(xmlXPathObjectPtr cur) {
2069 switch(cur->type) {
2070 case XPATH_NODESET: {
2071 int i;
2072 xmlNodePtr node;
2073#ifdef LIBXML_OUTPUT_ENABLED
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002074 xmlOutputBufferPtr buf;
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002075
Daniel Veillardbdc64d62012-03-27 14:41:37 +08002076 if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr <= 0)) {
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002077 fprintf(stderr, "XPath set is empty\n");
2078 progresult = XMLLINT_ERR_XPATH;
2079 break;
2080 }
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002081 buf = xmlOutputBufferCreateFile(stdout, NULL);
2082 if (buf == NULL) {
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002083 fprintf(stderr, "Out of memory for XPath\n");
2084 progresult = XMLLINT_ERR_MEM;
2085 return;
2086 }
2087 for (i = 0;i < cur->nodesetval->nodeNr;i++) {
2088 node = cur->nodesetval->nodeTab[i];
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002089 xmlNodeDumpOutput(buf, node->doc, node, 0, 0, NULL);
2090 xmlOutputBufferWrite(buf, 1, "\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002091 }
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002092 xmlOutputBufferClose(buf);
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002093#else
2094 printf("xpath returned %d nodes\n", cur->nodesetval->nodeNr);
2095#endif
2096 break;
2097 }
2098 case XPATH_BOOLEAN:
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002099 if (cur->boolval) printf("true\n");
2100 else printf("false\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002101 break;
2102 case XPATH_NUMBER:
2103 switch (xmlXPathIsInf(cur->floatval)) {
2104 case 1:
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002105 printf("Infinity\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002106 break;
2107 case -1:
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002108 printf("-Infinity\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002109 break;
2110 default:
2111 if (xmlXPathIsNaN(cur->floatval)) {
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002112 printf("NaN\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002113 } else {
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002114 printf("%0g\n", cur->floatval);
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002115 }
2116 }
2117 break;
2118 case XPATH_STRING:
Elliott Hughes7fbecab2019-01-10 16:42:03 -08002119 printf("%s\n", (const char *) cur->stringval);
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002120 break;
2121 case XPATH_UNDEFINED:
2122 fprintf(stderr, "XPath Object is uninitialized\n");
2123 progresult = XMLLINT_ERR_XPATH;
2124 break;
2125 default:
2126 fprintf(stderr, "XPath object of unexpected type\n");
2127 progresult = XMLLINT_ERR_XPATH;
2128 break;
2129 }
2130}
2131
2132static void doXPathQuery(xmlDocPtr doc, const char *query) {
2133 xmlXPathContextPtr ctxt;
2134 xmlXPathObjectPtr res;
2135
2136 ctxt = xmlXPathNewContext(doc);
2137 if (ctxt == NULL) {
2138 fprintf(stderr, "Out of memory for XPath\n");
2139 progresult = XMLLINT_ERR_MEM;
2140 return;
2141 }
Daniel Veillard2e1eaca2012-05-25 16:44:20 +08002142 ctxt->node = (xmlNodePtr) doc;
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002143 res = xmlXPathEval(BAD_CAST query, ctxt);
2144 xmlXPathFreeContext(ctxt);
2145
2146 if (res == NULL) {
2147 fprintf(stderr, "XPath evaluation failure\n");
2148 progresult = XMLLINT_ERR_XPATH;
2149 return;
2150 }
2151 doXPathDump(res);
2152 xmlXPathFreeObject(res);
2153}
2154#endif /* LIBXML_XPATH_ENABLED */
2155
Daniel Veillard7704fb12003-01-03 16:19:51 +00002156/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +02002157 * *
2158 * Tree Test processing *
2159 * *
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002160 ************************************************************************/
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002161static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
Daniel Veillard652327a2003-09-29 18:02:38 +00002162 xmlDocPtr doc = NULL;
2163#ifdef LIBXML_TREE_ENABLED
2164 xmlDocPtr tmp;
2165#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002166
Daniel Veillard48b2f892001-02-25 16:11:03 +00002167 if ((timing) && (!repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00002168 startTimer();
Daniel Veillardf1edb102009-08-10 14:43:18 +02002169
Daniel Veillard48b2f892001-02-25 16:11:03 +00002170
Daniel Veillard652327a2003-09-29 18:02:38 +00002171#ifdef LIBXML_TREE_ENABLED
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002172 if (filename == NULL) {
2173 if (generate) {
2174 xmlNodePtr n;
2175
2176 doc = xmlNewDoc(BAD_CAST "1.0");
Daniel Veillard95ddcd32004-10-26 21:53:55 +00002177 n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002178 xmlNodeSetContent(n, BAD_CAST "abc");
2179 xmlDocSetRootElement(doc, n);
2180 }
2181 }
Daniel Veillard652327a2003-09-29 18:02:38 +00002182#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002183#ifdef LIBXML_HTML_ENABLED
Daniel Veillard73b013f2003-09-30 12:36:01 +00002184#ifdef LIBXML_PUSH_ENABLED
William M. Brack78637da2003-07-31 14:47:38 +00002185 else if ((html) && (push)) {
2186 FILE *f;
2187
William M. Brack3403add2004-06-27 02:07:51 +00002188#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2189 f = fopen(filename, "rb");
Patrick Monnerat1c43f432013-12-12 15:12:53 +08002190#elif defined(__OS400__)
2191 f = fopen(filename, "rb");
William M. Brack3403add2004-06-27 02:07:51 +00002192#else
2193 f = fopen(filename, "r");
2194#endif
William M. Brack78637da2003-07-31 14:47:38 +00002195 if (f != NULL) {
Daniel Veillard1abd2212012-10-25 15:37:50 +08002196 int res;
William M. Brack78637da2003-07-31 14:47:38 +00002197 char chars[4096];
2198 htmlParserCtxtPtr ctxt;
2199
William M. Brack78637da2003-07-31 14:47:38 +00002200 res = fread(chars, 1, 4, f);
2201 if (res > 0) {
2202 ctxt = htmlCreatePushParserCtxt(NULL, NULL,
William M. Brack1d75c8a2003-10-27 13:48:16 +00002203 chars, res, filename, XML_CHAR_ENCODING_NONE);
Arnold Hendriks826bc322013-11-29 14:12:12 +08002204 xmlCtxtUseOptions(ctxt, options);
Daniel Veillard1abd2212012-10-25 15:37:50 +08002205 while ((res = fread(chars, 1, pushsize, f)) > 0) {
William M. Brack78637da2003-07-31 14:47:38 +00002206 htmlParseChunk(ctxt, chars, res, 0);
2207 }
2208 htmlParseChunk(ctxt, chars, 0, 1);
2209 doc = ctxt->myDoc;
2210 htmlFreeParserCtxt(ctxt);
2211 }
2212 fclose(f);
2213 }
2214 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00002215#endif /* LIBXML_PUSH_ENABLED */
Daniel Richard G5706b6d2012-08-06 11:32:54 +08002216#ifdef HAVE_MMAP
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002217 else if ((html) && (memory)) {
2218 int fd;
2219 struct stat info;
2220 const char *base;
Daniel Veillardf1edb102009-08-10 14:43:18 +02002221 if (stat(filename, &info) < 0)
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002222 return;
2223 if ((fd = open(filename, O_RDONLY)) < 0)
2224 return;
2225 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillardb98c6a02013-07-12 12:08:40 +08002226 if (base == (void *) MAP_FAILED) {
2227 close(fd);
2228 fprintf(stderr, "mmap failure for file %s\n", filename);
2229 progresult = XMLLINT_ERR_RDFILE;
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002230 return;
Daniel Veillardb98c6a02013-07-12 12:08:40 +08002231 }
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002232
2233 doc = htmlReadMemory((char *) base, info.st_size, filename,
2234 NULL, options);
Daniel Veillardf1edb102009-08-10 14:43:18 +02002235
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002236 munmap((char *) base, info.st_size);
2237 close(fd);
2238 }
2239#endif
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002240 else if (html) {
Daniel Veillard9475a352003-09-26 12:47:50 +00002241 doc = htmlReadFile(filename, NULL, options);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002242 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002243#endif /* LIBXML_HTML_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002244 else {
Daniel Veillard73b013f2003-09-30 12:36:01 +00002245#ifdef LIBXML_PUSH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002246 /*
2247 * build an XML tree from a string;
2248 */
2249 if (push) {
2250 FILE *f;
2251
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002252 /* '-' Usually means stdin -<sven@zen.org> */
2253 if ((filename[0] == '-') && (filename[1] == 0)) {
2254 f = stdin;
2255 } else {
William M. Brack3403add2004-06-27 02:07:51 +00002256#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2257 f = fopen(filename, "rb");
Patrick Monnerat1c43f432013-12-12 15:12:53 +08002258#elif defined(__OS400__)
2259 f = fopen(filename, "rb");
William M. Brack3403add2004-06-27 02:07:51 +00002260#else
2261 f = fopen(filename, "r");
2262#endif
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002263 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002264 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +00002265 int ret;
Daniel Veillarda880b122003-04-21 21:36:41 +00002266 int res, size = 1024;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002267 char chars[1024];
2268 xmlParserCtxtPtr ctxt;
2269
Daniel Veillarda880b122003-04-21 21:36:41 +00002270 /* if (repeat) size = 1024; */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002271 res = fread(chars, 1, 4, f);
2272 if (res > 0) {
2273 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
2274 chars, res, filename);
Daniel Veillard500a1de2004-03-22 15:22:58 +00002275 xmlCtxtUseOptions(ctxt, options);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002276 while ((res = fread(chars, 1, size, f)) > 0) {
2277 xmlParseChunk(ctxt, chars, res, 0);
2278 }
2279 xmlParseChunk(ctxt, chars, 0, 1);
2280 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +00002281 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002282 xmlFreeParserCtxt(ctxt);
Daniel Veillarde715dd22000-08-29 18:29:38 +00002283 if (!ret) {
2284 xmlFreeDoc(doc);
2285 doc = NULL;
2286 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002287 }
Daniel Veillard84bff682009-09-11 15:30:19 +02002288 if (f != stdin)
2289 fclose(f);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002290 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00002291 } else
2292#endif /* LIBXML_PUSH_ENABLED */
2293 if (testIO) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002294 if ((filename[0] == '-') && (filename[1] == 0)) {
Daniel Veillard60942de2003-09-25 21:05:58 +00002295 doc = xmlReadFd(0, NULL, NULL, options);
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002296 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002297 FILE *f;
Daniel Veillard5e873c42000-04-12 13:27:38 +00002298
William M. Brack3403add2004-06-27 02:07:51 +00002299#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2300 f = fopen(filename, "rb");
Patrick Monnerat1c43f432013-12-12 15:12:53 +08002301#elif defined(__OS400__)
2302 f = fopen(filename, "rb");
William M. Brack3403add2004-06-27 02:07:51 +00002303#else
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002304 f = fopen(filename, "r");
William M. Brack3403add2004-06-27 02:07:51 +00002305#endif
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002306 if (f != NULL) {
2307 if (rectxt == NULL)
Nick Wellnhofer86615e42017-11-09 17:47:47 +01002308 doc = xmlReadIO(myRead, myClose, f, filename, NULL,
2309 options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002310 else
Nick Wellnhofer86615e42017-11-09 17:47:47 +01002311 doc = xmlCtxtReadIO(rectxt, myRead, myClose, f,
2312 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002313 } else
Daniel Veillard5e873c42000-04-12 13:27:38 +00002314 doc = NULL;
Daniel Veillard5e873c42000-04-12 13:27:38 +00002315 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002316 } else if (htmlout) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002317 xmlParserCtxtPtr ctxt;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002318
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002319 if (rectxt == NULL)
2320 ctxt = xmlNewParserCtxt();
2321 else
2322 ctxt = rectxt;
Daniel Veillardf1edb102009-08-10 14:43:18 +02002323 if (ctxt == NULL) {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002324 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +00002325 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002326 ctxt->sax->error = xmlHTMLError;
2327 ctxt->sax->warning = xmlHTMLWarning;
2328 ctxt->vctxt.error = xmlHTMLValidityError;
2329 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002330
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002331 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002332
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002333 if (rectxt == NULL)
2334 xmlFreeParserCtxt(ctxt);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002335 }
Daniel Richard G5706b6d2012-08-06 11:32:54 +08002336#ifdef HAVE_MMAP
Daniel Veillard46e370e2000-07-21 20:32:03 +00002337 } else if (memory) {
2338 int fd;
2339 struct stat info;
2340 const char *base;
Daniel Veillardf1edb102009-08-10 14:43:18 +02002341 if (stat(filename, &info) < 0)
Daniel Veillard46e370e2000-07-21 20:32:03 +00002342 return;
2343 if ((fd = open(filename, O_RDONLY)) < 0)
2344 return;
2345 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillarda75a0092013-05-08 13:45:48 +08002346 if (base == (void *) MAP_FAILED) {
Daniel Veillardb98c6a02013-07-12 12:08:40 +08002347 close(fd);
Daniel Veillarda75a0092013-05-08 13:45:48 +08002348 fprintf(stderr, "mmap failure for file %s\n", filename);
2349 progresult = XMLLINT_ERR_RDFILE;
Daniel Veillard46e370e2000-07-21 20:32:03 +00002350 return;
Daniel Veillarda75a0092013-05-08 13:45:48 +08002351 }
Daniel Veillard46e370e2000-07-21 20:32:03 +00002352
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002353 if (rectxt == NULL)
Daniel Veillard60942de2003-09-25 21:05:58 +00002354 doc = xmlReadMemory((char *) base, info.st_size,
2355 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002356 else
Daniel Veillard60942de2003-09-25 21:05:58 +00002357 doc = xmlCtxtReadMemory(rectxt, (char *) base, info.st_size,
2358 filename, NULL, options);
Daniel Veillardf1edb102009-08-10 14:43:18 +02002359
Daniel Veillard46e370e2000-07-21 20:32:03 +00002360 munmap((char *) base, info.st_size);
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002361 close(fd);
Daniel Veillard46e370e2000-07-21 20:32:03 +00002362#endif
Daniel Veillard4432df22003-09-28 18:58:27 +00002363#ifdef LIBXML_VALID_ENABLED
Daniel Veillardea7751d2002-12-20 00:16:24 +00002364 } else if (valid) {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002365 xmlParserCtxtPtr ctxt = NULL;
Daniel Veillardea7751d2002-12-20 00:16:24 +00002366
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002367 if (rectxt == NULL)
2368 ctxt = xmlNewParserCtxt();
2369 else
2370 ctxt = rectxt;
Daniel Veillardf1edb102009-08-10 14:43:18 +02002371 if (ctxt == NULL) {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002372 doc = NULL;
Daniel Veillardea7751d2002-12-20 00:16:24 +00002373 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002374 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
2375
2376 if (ctxt->valid == 0)
William M. Brack8304d872004-06-08 13:29:32 +00002377 progresult = XMLLINT_ERR_RDFILE;
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002378 if (rectxt == NULL)
2379 xmlFreeParserCtxt(ctxt);
Daniel Veillardea7751d2002-12-20 00:16:24 +00002380 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002381#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardea7751d2002-12-20 00:16:24 +00002382 } else {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002383 if (rectxt != NULL)
2384 doc = xmlCtxtReadFile(rectxt, filename, NULL, options);
Daniel Veillard81562d22005-06-15 13:27:56 +00002385 else {
2386#ifdef LIBXML_SAX1_ENABLED
2387 if (sax1)
2388 doc = xmlParseFile(filename);
2389 else
2390#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002391 doc = xmlReadFile(filename, NULL, options);
Daniel Veillard81562d22005-06-15 13:27:56 +00002392 }
Daniel Veillardea7751d2002-12-20 00:16:24 +00002393 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002394 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002395
Daniel Veillard88a172f2000-08-04 18:23:10 +00002396 /*
2397 * If we don't have a document we might as well give up. Do we
2398 * want an error message here? <sven@zen.org> */
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002399 if (doc == NULL) {
William M. Brack8304d872004-06-08 13:29:32 +00002400 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard88a172f2000-08-04 18:23:10 +00002401 return;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002402 }
2403
Daniel Veillard48b2f892001-02-25 16:11:03 +00002404 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002405 endTimer("Parsing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002406 }
2407
Daniel Veillard29e43992001-12-13 22:21:58 +00002408 /*
2409 * Remove DOCTYPE nodes
2410 */
2411 if (dropdtd) {
2412 xmlDtdPtr dtd;
2413
2414 dtd = xmlGetIntSubset(doc);
2415 if (dtd != NULL) {
2416 xmlUnlinkNode((xmlNodePtr)dtd);
2417 xmlFreeDtd(dtd);
2418 }
2419 }
2420
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002421#ifdef LIBXML_XINCLUDE_ENABLED
Daniel Veillard48b2f892001-02-25 16:11:03 +00002422 if (xinclude) {
2423 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002424 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002425 }
William M. Brack4e1c2db2005-02-11 10:58:55 +00002426 if (xmlXIncludeProcessFlags(doc, options) < 0)
2427 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard48b2f892001-02-25 16:11:03 +00002428 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002429 endTimer("Xinclude processing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002430 }
2431 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002432#endif
Daniel Veillard88a172f2000-08-04 18:23:10 +00002433
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002434#ifdef LIBXML_XPATH_ENABLED
2435 if (xpathquery != NULL) {
2436 doXPathQuery(doc, xpathquery);
2437 }
2438#endif
2439
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002440#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00002441#ifdef LIBXML_XPATH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002442 /*
Daniel Veillardcbaf3992001-12-31 16:16:02 +00002443 * shell interaction
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002444 */
Daniel Veillard26a45c82006-10-20 12:55:34 +00002445 if (shell) {
2446 xmlXPathOrderDocElems(doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002447 xmlShell(doc, filename, xmlShellReadline, stdout);
Daniel Veillard26a45c82006-10-20 12:55:34 +00002448 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002449#endif
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00002450#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002451
Daniel Veillard652327a2003-09-29 18:02:38 +00002452#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002453 /*
2454 * test intermediate copy if needed.
2455 */
2456 if (copy) {
2457 tmp = doc;
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002458 if (timing) {
2459 startTimer();
2460 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002461 doc = xmlCopyDoc(doc, 1);
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002462 if (timing) {
2463 endTimer("Copying");
2464 }
2465 if (timing) {
2466 startTimer();
2467 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002468 xmlFreeDoc(tmp);
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002469 if (timing) {
2470 endTimer("Freeing original");
2471 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002472 }
Daniel Veillard652327a2003-09-29 18:02:38 +00002473#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002474
Daniel Veillard4432df22003-09-28 18:58:27 +00002475#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002476 if ((insert) && (!html)) {
2477 const xmlChar* list[256];
2478 int nb, i;
2479 xmlNodePtr node;
2480
2481 if (doc->children != NULL) {
2482 node = doc->children;
2483 while ((node != NULL) && (node->last == NULL)) node = node->next;
2484 if (node != NULL) {
2485 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
2486 if (nb < 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002487 fprintf(stderr, "could not get valid list of elements\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002488 } else if (nb == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002489 fprintf(stderr, "No element can be inserted under root\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002490 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002491 fprintf(stderr, "%d element types can be inserted under root:\n",
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002492 nb);
2493 for (i = 0;i < nb;i++) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002494 fprintf(stderr, "%s\n", (char *) list[i]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002495 }
2496 }
2497 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02002498 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002499 }else
2500#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002501#ifdef LIBXML_READER_ENABLED
2502 if (walker) {
2503 walkDoc(doc);
2504 }
2505#endif /* LIBXML_READER_ENABLED */
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002506#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard4432df22003-09-28 18:58:27 +00002507 if (noout == 0) {
Daniel Veillard3df01182003-12-10 10:17:51 +00002508 int ret;
2509
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002510 /*
2511 * print it.
2512 */
2513#ifdef LIBXML_DEBUG_ENABLED
2514 if (!debug) {
2515#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00002516 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002517 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002518 }
Daniel Veillard656ce942004-04-30 23:11:45 +00002519#ifdef LIBXML_HTML_ENABLED
Daniel Veillard42fd4122003-11-04 08:47:48 +00002520 if ((html) && (!xmlout)) {
2521 if (compress) {
2522 htmlSaveFile(output ? output : "-", doc);
2523 }
2524 else if (encoding != NULL) {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002525 if (format == 1) {
Daniel Veillard42fd4122003-11-04 08:47:48 +00002526 htmlSaveFileFormat(output ? output : "-", doc, encoding, 1);
2527 }
2528 else {
2529 htmlSaveFileFormat(output ? output : "-", doc, encoding, 0);
2530 }
2531 }
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002532 else if (format == 1) {
Daniel Veillard42fd4122003-11-04 08:47:48 +00002533 htmlSaveFileFormat(output ? output : "-", doc, NULL, 1);
2534 }
2535 else {
2536 FILE *out;
2537 if (output == NULL)
2538 out = stdout;
2539 else {
2540 out = fopen(output,"wb");
2541 }
2542 if (out != NULL) {
2543 if (htmlDocDump(out, doc) < 0)
William M. Brack8304d872004-06-08 13:29:32 +00002544 progresult = XMLLINT_ERR_OUT;
Daniel Veillard42fd4122003-11-04 08:47:48 +00002545
2546 if (output != NULL)
2547 fclose(out);
2548 } else {
2549 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00002550 progresult = XMLLINT_ERR_OUT;
Daniel Veillard42fd4122003-11-04 08:47:48 +00002551 }
2552 }
2553 if ((timing) && (!repeat)) {
2554 endTimer("Saving");
2555 }
2556 } else
2557#endif
Daniel Veillard25048d82004-08-14 22:37:54 +00002558#ifdef LIBXML_C14N_ENABLED
2559 if (canonical) {
2560 xmlChar *result = NULL;
2561 int size;
2562
Aleksey Sanin83868242009-07-09 10:26:22 +02002563 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_0, NULL, 1, &result);
2564 if (size >= 0) {
Stefan Kostdff8d0f2011-05-09 12:14:59 +03002565 if (write(1, result, size) == -1) {
2566 fprintf(stderr, "Can't write data\n");
2567 }
Aleksey Sanin83868242009-07-09 10:26:22 +02002568 xmlFree(result);
2569 } else {
2570 fprintf(stderr, "Failed to canonicalize\n");
2571 progresult = XMLLINT_ERR_OUT;
2572 }
Sérgio Batistad9ea9132014-06-09 22:10:15 +08002573 } else if (canonical_11) {
Aleksey Sanin83868242009-07-09 10:26:22 +02002574 xmlChar *result = NULL;
2575 int size;
2576
2577 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_1, NULL, 1, &result);
Daniel Veillard25048d82004-08-14 22:37:54 +00002578 if (size >= 0) {
Stefan Kostdff8d0f2011-05-09 12:14:59 +03002579 if (write(1, result, size) == -1) {
2580 fprintf(stderr, "Can't write data\n");
2581 }
Daniel Veillard25048d82004-08-14 22:37:54 +00002582 xmlFree(result);
2583 } else {
2584 fprintf(stderr, "Failed to canonicalize\n");
2585 progresult = XMLLINT_ERR_OUT;
2586 }
2587 } else
Aleksey Sanin2650df12005-06-06 17:16:50 +00002588 if (exc_canonical) {
2589 xmlChar *result = NULL;
2590 int size;
2591
Aleksey Sanin83868242009-07-09 10:26:22 +02002592 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_EXCLUSIVE_1_0, NULL, 1, &result);
Aleksey Sanin2650df12005-06-06 17:16:50 +00002593 if (size >= 0) {
Stefan Kostdff8d0f2011-05-09 12:14:59 +03002594 if (write(1, result, size) == -1) {
2595 fprintf(stderr, "Can't write data\n");
2596 }
Aleksey Sanin2650df12005-06-06 17:16:50 +00002597 xmlFree(result);
2598 } else {
2599 fprintf(stderr, "Failed to canonicalize\n");
2600 progresult = XMLLINT_ERR_OUT;
2601 }
2602 } else
Daniel Veillard25048d82004-08-14 22:37:54 +00002603#endif
Daniel Richard G5706b6d2012-08-06 11:32:54 +08002604#ifdef HAVE_MMAP
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002605 if (memory) {
2606 xmlChar *result;
2607 int len;
2608
2609 if (encoding != NULL) {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002610 if (format == 1) {
Daniel Veillardd536f702001-11-08 17:32:47 +00002611 xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
Daniel Veillardf1edb102009-08-10 14:43:18 +02002612 } else {
Daniel Veillardd536f702001-11-08 17:32:47 +00002613 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
2614 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002615 } else {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002616 if (format == 1)
Daniel Veillard90493a92001-08-14 14:12:47 +00002617 xmlDocDumpFormatMemory(doc, &result, &len, 1);
2618 else
2619 xmlDocDumpMemory(doc, &result, &len);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002620 }
2621 if (result == NULL) {
2622 fprintf(stderr, "Failed to save\n");
Daniel Veillard25048d82004-08-14 22:37:54 +00002623 progresult = XMLLINT_ERR_OUT;
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002624 } else {
Stefan Kostdff8d0f2011-05-09 12:14:59 +03002625 if (write(1, result, len) == -1) {
2626 fprintf(stderr, "Can't write data\n");
2627 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002628 xmlFree(result);
2629 }
Daniel Veillarddab39b52006-10-16 23:22:10 +00002630
Daniel Veillard3b2c2612001-04-04 00:09:00 +00002631 } else
Daniel Richard G5706b6d2012-08-06 11:32:54 +08002632#endif /* HAVE_MMAP */
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002633 if (compress) {
2634 xmlSaveFile(output ? output : "-", doc);
Daniel Veillarddab39b52006-10-16 23:22:10 +00002635 } else if (oldout) {
2636 if (encoding != NULL) {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002637 if (format == 1) {
Daniel Veillarddab39b52006-10-16 23:22:10 +00002638 ret = xmlSaveFormatFileEnc(output ? output : "-", doc,
2639 encoding, 1);
2640 }
2641 else {
2642 ret = xmlSaveFileEnc(output ? output : "-", doc,
2643 encoding);
2644 }
2645 if (ret < 0) {
2646 fprintf(stderr, "failed save to %s\n",
2647 output ? output : "-");
2648 progresult = XMLLINT_ERR_OUT;
2649 }
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002650 } else if (format == 1) {
Daniel Veillarddab39b52006-10-16 23:22:10 +00002651 ret = xmlSaveFormatFile(output ? output : "-", doc, 1);
2652 if (ret < 0) {
2653 fprintf(stderr, "failed save to %s\n",
2654 output ? output : "-");
2655 progresult = XMLLINT_ERR_OUT;
2656 }
Daniel Veillard05d987b2003-10-08 11:54:57 +00002657 } else {
Daniel Veillarddab39b52006-10-16 23:22:10 +00002658 FILE *out;
2659 if (output == NULL)
2660 out = stdout;
2661 else {
2662 out = fopen(output,"wb");
2663 }
2664 if (out != NULL) {
2665 if (xmlDocDump(out, doc) < 0)
2666 progresult = XMLLINT_ERR_OUT;
2667
2668 if (output != NULL)
2669 fclose(out);
2670 } else {
2671 fprintf(stderr, "failed to open %s\n", output);
2672 progresult = XMLLINT_ERR_OUT;
2673 }
2674 }
2675 } else {
2676 xmlSaveCtxtPtr ctxt;
2677 int saveOpts = 0;
2678
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002679 if (format == 1)
Daniel Veillarddab39b52006-10-16 23:22:10 +00002680 saveOpts |= XML_SAVE_FORMAT;
Adam Spraggd2e62312010-11-03 15:33:40 +01002681 else if (format == 2)
2682 saveOpts |= XML_SAVE_WSNONSIG;
Daniel Veillard9ccea572010-03-10 15:02:49 +01002683
2684#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
Daniel Veillard9d962642009-08-23 15:31:18 +02002685 if (xmlout)
2686 saveOpts |= XML_SAVE_AS_XML;
Daniel Veillard9ccea572010-03-10 15:02:49 +01002687#endif
Daniel Veillarddab39b52006-10-16 23:22:10 +00002688
2689 if (output == NULL)
2690 ctxt = xmlSaveToFd(1, encoding, saveOpts);
2691 else
2692 ctxt = xmlSaveToFilename(output, encoding, saveOpts);
2693
2694 if (ctxt != NULL) {
2695 if (xmlSaveDoc(ctxt, doc) < 0) {
2696 fprintf(stderr, "failed save to %s\n",
2697 output ? output : "-");
2698 progresult = XMLLINT_ERR_OUT;
2699 }
2700 xmlSaveClose(ctxt);
2701 } else {
William M. Brack8304d872004-06-08 13:29:32 +00002702 progresult = XMLLINT_ERR_OUT;
Daniel Veillard05d987b2003-10-08 11:54:57 +00002703 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002704 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002705 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002706 endTimer("Saving");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002707 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002708#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002709 } else {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002710 FILE *out;
2711 if (output == NULL)
2712 out = stdout;
2713 else {
2714 out = fopen(output,"wb");
2715 }
Daniel Veillard05d987b2003-10-08 11:54:57 +00002716 if (out != NULL) {
2717 xmlDebugDumpDocument(out, doc);
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002718
Daniel Veillard05d987b2003-10-08 11:54:57 +00002719 if (output != NULL)
2720 fclose(out);
2721 } else {
2722 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00002723 progresult = XMLLINT_ERR_OUT;
Daniel Veillard05d987b2003-10-08 11:54:57 +00002724 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002725 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002726#endif
2727 }
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002728#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002729
Daniel Veillard4432df22003-09-28 18:58:27 +00002730#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002731 /*
2732 * A posteriori validation test
2733 */
Daniel Veillard66f68e72003-08-18 16:39:51 +00002734 if ((dtdvalid != NULL) || (dtdvalidfpi != NULL)) {
Daniel Veillardcd429612000-10-11 15:57:05 +00002735 xmlDtdPtr dtd;
2736
Daniel Veillard48b2f892001-02-25 16:11:03 +00002737 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002738 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002739 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00002740 if (dtdvalid != NULL)
Daniel Veillardf1edb102009-08-10 14:43:18 +02002741 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
Daniel Veillard66f68e72003-08-18 16:39:51 +00002742 else
Daniel Veillardf1edb102009-08-10 14:43:18 +02002743 dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL);
Daniel Veillard48b2f892001-02-25 16:11:03 +00002744 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002745 endTimer("Parsing DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002746 }
Daniel Veillardcd429612000-10-11 15:57:05 +00002747 if (dtd == NULL) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00002748 if (dtdvalid != NULL)
2749 xmlGenericError(xmlGenericErrorContext,
2750 "Could not parse DTD %s\n", dtdvalid);
2751 else
2752 xmlGenericError(xmlGenericErrorContext,
2753 "Could not parse DTD %s\n", dtdvalidfpi);
William M. Brack8304d872004-06-08 13:29:32 +00002754 progresult = XMLLINT_ERR_DTD;
Daniel Veillardcd429612000-10-11 15:57:05 +00002755 } else {
Daniel Veillarda37aab82003-06-09 09:10:36 +00002756 xmlValidCtxtPtr cvp;
2757
2758 if ((cvp = xmlNewValidCtxt()) == NULL) {
2759 xmlGenericError(xmlGenericErrorContext,
2760 "Couldn't allocate validation context\n");
2761 exit(-1);
2762 }
2763 cvp->userData = (void *) stderr;
2764 cvp->error = (xmlValidityErrorFunc) fprintf;
2765 cvp->warning = (xmlValidityWarningFunc) fprintf;
2766
Daniel Veillard48b2f892001-02-25 16:11:03 +00002767 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002768 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002769 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002770 if (!xmlValidateDtd(cvp, doc, dtd)) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00002771 if (dtdvalid != NULL)
2772 xmlGenericError(xmlGenericErrorContext,
2773 "Document %s does not validate against %s\n",
2774 filename, dtdvalid);
2775 else
2776 xmlGenericError(xmlGenericErrorContext,
2777 "Document %s does not validate against %s\n",
2778 filename, dtdvalidfpi);
William M. Brack8304d872004-06-08 13:29:32 +00002779 progresult = XMLLINT_ERR_VALID;
Daniel Veillardcd429612000-10-11 15:57:05 +00002780 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002781 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002782 endTimer("Validating against DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002783 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002784 xmlFreeValidCtxt(cvp);
Daniel Veillardcd429612000-10-11 15:57:05 +00002785 xmlFreeDtd(dtd);
2786 }
2787 } else if (postvalid) {
Daniel Veillarda37aab82003-06-09 09:10:36 +00002788 xmlValidCtxtPtr cvp;
2789
2790 if ((cvp = xmlNewValidCtxt()) == NULL) {
2791 xmlGenericError(xmlGenericErrorContext,
2792 "Couldn't allocate validation context\n");
2793 exit(-1);
2794 }
2795
Daniel Veillard48b2f892001-02-25 16:11:03 +00002796 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002797 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002798 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002799 cvp->userData = (void *) stderr;
2800 cvp->error = (xmlValidityErrorFunc) fprintf;
2801 cvp->warning = (xmlValidityWarningFunc) fprintf;
2802 if (!xmlValidateDocument(cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00002803 xmlGenericError(xmlGenericErrorContext,
2804 "Document %s does not validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002805 progresult = XMLLINT_ERR_VALID;
Daniel Veillardcd429612000-10-11 15:57:05 +00002806 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002807 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002808 endTimer("Validating");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002809 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002810 xmlFreeValidCtxt(cvp);
Daniel Veillard4432df22003-09-28 18:58:27 +00002811 }
2812#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardd4501d72005-07-24 14:27:16 +00002813#ifdef LIBXML_SCHEMATRON_ENABLED
2814 if (wxschematron != NULL) {
2815 xmlSchematronValidCtxtPtr ctxt;
2816 int ret;
Daniel Veillardc740a172005-07-31 12:17:24 +00002817 int flag;
Daniel Veillardd4501d72005-07-24 14:27:16 +00002818
2819 if ((timing) && (!repeat)) {
2820 startTimer();
2821 }
2822
2823 if (debug)
2824 flag = XML_SCHEMATRON_OUT_XML;
Daniel Veillardc740a172005-07-31 12:17:24 +00002825 else
2826 flag = XML_SCHEMATRON_OUT_TEXT;
2827 if (noout)
2828 flag |= XML_SCHEMATRON_OUT_QUIET;
Daniel Veillardd4501d72005-07-24 14:27:16 +00002829 ctxt = xmlSchematronNewValidCtxt(wxschematron, flag);
2830#if 0
2831 xmlSchematronSetValidErrors(ctxt,
2832 (xmlSchematronValidityErrorFunc) fprintf,
2833 (xmlSchematronValidityWarningFunc) fprintf,
2834 stderr);
2835#endif
2836 ret = xmlSchematronValidateDoc(ctxt, doc);
2837 if (ret == 0) {
2838 fprintf(stderr, "%s validates\n", filename);
2839 } else if (ret > 0) {
2840 fprintf(stderr, "%s fails to validate\n", filename);
2841 progresult = XMLLINT_ERR_VALID;
2842 } else {
2843 fprintf(stderr, "%s validation generated an internal error\n",
2844 filename);
2845 progresult = XMLLINT_ERR_VALID;
2846 }
2847 xmlSchematronFreeValidCtxt(ctxt);
2848 if ((timing) && (!repeat)) {
2849 endTimer("Validating");
2850 }
2851 }
2852#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00002853#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard4432df22003-09-28 18:58:27 +00002854 if (relaxngschemas != NULL) {
Daniel Veillard71531f32003-02-05 13:19:53 +00002855 xmlRelaxNGValidCtxtPtr ctxt;
2856 int ret;
2857
Daniel Veillard42f12e92003-03-07 18:32:59 +00002858 if ((timing) && (!repeat)) {
2859 startTimer();
2860 }
2861
Daniel Veillard71531f32003-02-05 13:19:53 +00002862 ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
2863 xmlRelaxNGSetValidErrors(ctxt,
2864 (xmlRelaxNGValidityErrorFunc) fprintf,
2865 (xmlRelaxNGValidityWarningFunc) fprintf,
2866 stderr);
2867 ret = xmlRelaxNGValidateDoc(ctxt, doc);
2868 if (ret == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002869 fprintf(stderr, "%s validates\n", filename);
Daniel Veillard71531f32003-02-05 13:19:53 +00002870 } else if (ret > 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002871 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002872 progresult = XMLLINT_ERR_VALID;
Daniel Veillard71531f32003-02-05 13:19:53 +00002873 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002874 fprintf(stderr, "%s validation generated an internal error\n",
Daniel Veillard71531f32003-02-05 13:19:53 +00002875 filename);
William M. Brack8304d872004-06-08 13:29:32 +00002876 progresult = XMLLINT_ERR_VALID;
Daniel Veillard71531f32003-02-05 13:19:53 +00002877 }
2878 xmlRelaxNGFreeValidCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00002879 if ((timing) && (!repeat)) {
2880 endTimer("Validating");
2881 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002882 } else if (wxschemas != NULL) {
2883 xmlSchemaValidCtxtPtr ctxt;
2884 int ret;
2885
2886 if ((timing) && (!repeat)) {
2887 startTimer();
2888 }
2889
2890 ctxt = xmlSchemaNewValidCtxt(wxschemas);
2891 xmlSchemaSetValidErrors(ctxt,
2892 (xmlSchemaValidityErrorFunc) fprintf,
2893 (xmlSchemaValidityWarningFunc) fprintf,
2894 stderr);
2895 ret = xmlSchemaValidateDoc(ctxt, doc);
2896 if (ret == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002897 fprintf(stderr, "%s validates\n", filename);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002898 } else if (ret > 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002899 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002900 progresult = XMLLINT_ERR_VALID;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002901 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002902 fprintf(stderr, "%s validation generated an internal error\n",
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002903 filename);
William M. Brack8304d872004-06-08 13:29:32 +00002904 progresult = XMLLINT_ERR_VALID;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002905 }
2906 xmlSchemaFreeValidCtxt(ctxt);
2907 if ((timing) && (!repeat)) {
2908 endTimer("Validating");
2909 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002910 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002911#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002912
2913#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillard6b099012008-11-06 13:47:39 +00002914#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002915 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00002916 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002917#endif
Daniel Veillard6b099012008-11-06 13:47:39 +00002918#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002919
2920 /*
2921 * free it.
2922 */
Daniel Veillard48b2f892001-02-25 16:11:03 +00002923 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002924 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002925 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002926 xmlFreeDoc(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +00002927 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002928 endTimer("Freeing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002929 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002930}
2931
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002932/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +02002933 * *
2934 * Usage and Main *
2935 * *
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002936 ************************************************************************/
2937
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002938static void showVersion(const char *name) {
2939 fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
2940 fprintf(stderr, " compiled with: ");
Daniel Veillard602434d2005-09-12 09:20:31 +00002941 if (xmlHasFeature(XML_WITH_THREAD)) fprintf(stderr, "Threads ");
2942 if (xmlHasFeature(XML_WITH_TREE)) fprintf(stderr, "Tree ");
2943 if (xmlHasFeature(XML_WITH_OUTPUT)) fprintf(stderr, "Output ");
2944 if (xmlHasFeature(XML_WITH_PUSH)) fprintf(stderr, "Push ");
2945 if (xmlHasFeature(XML_WITH_READER)) fprintf(stderr, "Reader ");
2946 if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(stderr, "Patterns ");
2947 if (xmlHasFeature(XML_WITH_WRITER)) fprintf(stderr, "Writer ");
2948 if (xmlHasFeature(XML_WITH_SAX1)) fprintf(stderr, "SAXv1 ");
Daniel Veillardf1edb102009-08-10 14:43:18 +02002949 if (xmlHasFeature(XML_WITH_FTP)) fprintf(stderr, "FTP ");
2950 if (xmlHasFeature(XML_WITH_HTTP)) fprintf(stderr, "HTTP ");
Daniel Veillard602434d2005-09-12 09:20:31 +00002951 if (xmlHasFeature(XML_WITH_VALID)) fprintf(stderr, "DTDValid ");
Daniel Veillardf1edb102009-08-10 14:43:18 +02002952 if (xmlHasFeature(XML_WITH_HTML)) fprintf(stderr, "HTML ");
2953 if (xmlHasFeature(XML_WITH_LEGACY)) fprintf(stderr, "Legacy ");
2954 if (xmlHasFeature(XML_WITH_C14N)) fprintf(stderr, "C14N ");
2955 if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(stderr, "Catalog ");
2956 if (xmlHasFeature(XML_WITH_XPATH)) fprintf(stderr, "XPath ");
2957 if (xmlHasFeature(XML_WITH_XPTR)) fprintf(stderr, "XPointer ");
2958 if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(stderr, "XInclude ");
2959 if (xmlHasFeature(XML_WITH_ICONV)) fprintf(stderr, "Iconv ");
David Kilzer783931f2016-03-02 12:48:51 -08002960 if (xmlHasFeature(XML_WITH_ICU)) fprintf(stderr, "ICU ");
Daniel Veillardf1edb102009-08-10 14:43:18 +02002961 if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(stderr, "ISO8859X ");
2962 if (xmlHasFeature(XML_WITH_UNICODE)) fprintf(stderr, "Unicode ");
2963 if (xmlHasFeature(XML_WITH_REGEXP)) fprintf(stderr, "Regexps ");
2964 if (xmlHasFeature(XML_WITH_AUTOMATA)) fprintf(stderr, "Automata ");
2965 if (xmlHasFeature(XML_WITH_EXPR)) fprintf(stderr, "Expr ");
2966 if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(stderr, "Schemas ");
2967 if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(stderr, "Schematron ");
2968 if (xmlHasFeature(XML_WITH_MODULES)) fprintf(stderr, "Modules ");
2969 if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(stderr, "Debug ");
2970 if (xmlHasFeature(XML_WITH_DEBUG_MEM)) fprintf(stderr, "MemDebug ");
2971 if (xmlHasFeature(XML_WITH_DEBUG_RUN)) fprintf(stderr, "RunDebug ");
Daniel Veillard75acfee2006-07-13 06:29:56 +00002972 if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(stderr, "Zlib ");
Anders F Bjorklundeae52612011-09-18 16:59:13 +02002973 if (xmlHasFeature(XML_WITH_LZMA)) fprintf(stderr, "Lzma ");
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002974 fprintf(stderr, "\n");
2975}
2976
Nick Wellnhoferf4353652017-06-20 16:19:33 +02002977static void usage(FILE *f, const char *name) {
2978 fprintf(f, "Usage : %s [options] XMLfiles ...\n", name);
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002979#ifdef LIBXML_OUTPUT_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02002980 fprintf(f, "\tParse the XML files and output the result of the parsing\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002981#else
Nick Wellnhoferf4353652017-06-20 16:19:33 +02002982 fprintf(f, "\tParse the XML files\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002983#endif /* LIBXML_OUTPUT_ENABLED */
Nick Wellnhoferf4353652017-06-20 16:19:33 +02002984 fprintf(f, "\t--version : display the version of the XML library used\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002985#ifdef LIBXML_DEBUG_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02002986 fprintf(f, "\t--debug : dump a debug tree of the in-memory document\n");
2987 fprintf(f, "\t--shell : run a navigating shell\n");
2988 fprintf(f, "\t--debugent : debug the entities defined in the document\n");
Daniel Veillard8326e732003-01-07 00:19:07 +00002989#else
Daniel Veillard81273902003-09-30 00:43:48 +00002990#ifdef LIBXML_READER_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02002991 fprintf(f, "\t--debug : dump the nodes content when using --stream\n");
Daniel Veillard81273902003-09-30 00:43:48 +00002992#endif /* LIBXML_READER_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002993#endif
Daniel Veillard652327a2003-09-29 18:02:38 +00002994#ifdef LIBXML_TREE_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02002995 fprintf(f, "\t--copy : used to test the internal copy implementation\n");
Daniel Veillard652327a2003-09-29 18:02:38 +00002996#endif /* LIBXML_TREE_ENABLED */
Nick Wellnhoferf4353652017-06-20 16:19:33 +02002997 fprintf(f, "\t--recover : output what was parsable on broken XML documents\n");
2998 fprintf(f, "\t--huge : remove any internal arbitrary parser limits\n");
2999 fprintf(f, "\t--noent : substitute entity references by their value\n");
3000 fprintf(f, "\t--noenc : ignore any encoding specified inside the document\n");
3001 fprintf(f, "\t--noout : don't output the result tree\n");
3002 fprintf(f, "\t--path 'paths': provide a set of paths for resources\n");
3003 fprintf(f, "\t--load-trace : print trace of all external entities loaded\n");
3004 fprintf(f, "\t--nonet : refuse to fetch DTDs or entities over network\n");
3005 fprintf(f, "\t--nocompact : do not generate compact text nodes\n");
3006 fprintf(f, "\t--htmlout : output results as HTML\n");
3007 fprintf(f, "\t--nowrap : do not put HTML doc wrapper\n");
Daniel Veillard4432df22003-09-28 18:58:27 +00003008#ifdef LIBXML_VALID_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003009 fprintf(f, "\t--valid : validate the document in addition to std well-formed check\n");
3010 fprintf(f, "\t--postvalid : do a posteriori validation, i.e after parsing\n");
3011 fprintf(f, "\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
3012 fprintf(f, "\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
Daniel Veillard4432df22003-09-28 18:58:27 +00003013#endif /* LIBXML_VALID_ENABLED */
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003014 fprintf(f, "\t--timing : print some timings\n");
3015 fprintf(f, "\t--output file or -o file: save to a given file\n");
3016 fprintf(f, "\t--repeat : repeat 100 times, for timing or profiling\n");
3017 fprintf(f, "\t--insert : ad-hoc test for valid insertions\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003018#ifdef LIBXML_OUTPUT_ENABLED
Nick Wellnhofercb5541c2017-11-13 17:08:38 +01003019#ifdef LIBXML_ZLIB_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003020 fprintf(f, "\t--compress : turn on gzip compression of output\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003021#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003022#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003023#ifdef LIBXML_HTML_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003024 fprintf(f, "\t--html : use the HTML parser\n");
3025 fprintf(f, "\t--xmlout : force to use the XML serializer when using --html\n");
3026 fprintf(f, "\t--nodefdtd : do not default HTML doctype\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003027#endif
Daniel Veillard73b013f2003-09-30 12:36:01 +00003028#ifdef LIBXML_PUSH_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003029 fprintf(f, "\t--push : use the push mode of the parser\n");
3030 fprintf(f, "\t--pushsmall : use the push mode of the parser using tiny increments\n");
Daniel Veillard73b013f2003-09-30 12:36:01 +00003031#endif /* LIBXML_PUSH_ENABLED */
Daniel Richard G5706b6d2012-08-06 11:32:54 +08003032#ifdef HAVE_MMAP
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003033 fprintf(f, "\t--memory : parse from memory\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003034#endif
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003035 fprintf(f, "\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n");
3036 fprintf(f, "\t--nowarning : do not emit warnings from parser/validator\n");
3037 fprintf(f, "\t--noblanks : drop (ignorable?) blanks spaces\n");
3038 fprintf(f, "\t--nocdata : replace cdata section with text nodes\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003039#ifdef LIBXML_OUTPUT_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003040 fprintf(f, "\t--format : reformat/reindent the output\n");
3041 fprintf(f, "\t--encode encoding : output in the given encoding\n");
3042 fprintf(f, "\t--dropdtd : remove the DOCTYPE of the input docs\n");
3043 fprintf(f, "\t--pretty STYLE : pretty-print in a particular style\n");
3044 fprintf(f, "\t 0 Do not pretty print\n");
3045 fprintf(f, "\t 1 Format the XML content, as --format\n");
3046 fprintf(f, "\t 2 Add whitespace inside tags, preserving content\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003047#endif /* LIBXML_OUTPUT_ENABLED */
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003048 fprintf(f, "\t--c14n : save in W3C canonical format v1.0 (with comments)\n");
3049 fprintf(f, "\t--c14n11 : save in W3C canonical format v1.1 (with comments)\n");
3050 fprintf(f, "\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n");
Daniel Veillard25048d82004-08-14 22:37:54 +00003051#ifdef LIBXML_C14N_ENABLED
3052#endif /* LIBXML_C14N_ENABLED */
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003053 fprintf(f, "\t--nsclean : remove redundant namespace declarations\n");
3054 fprintf(f, "\t--testIO : test user I/O support\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003055#ifdef LIBXML_CATALOG_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003056 fprintf(f, "\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
3057 fprintf(f, "\t otherwise XML Catalogs starting from \n");
3058 fprintf(f, "\t %s are activated by default\n", XML_XML_DEFAULT_CATALOG);
3059 fprintf(f, "\t--nocatalogs: deactivate all catalogs\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003060#endif
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003061 fprintf(f, "\t--auto : generate a small doc on the fly\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003062#ifdef LIBXML_XINCLUDE_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003063 fprintf(f, "\t--xinclude : do XInclude processing\n");
3064 fprintf(f, "\t--noxincludenode : same but do not generate XInclude nodes\n");
3065 fprintf(f, "\t--nofixup-base-uris : do not fixup xml:base uris\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003066#endif
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003067 fprintf(f, "\t--loaddtd : fetch external DTD\n");
3068 fprintf(f, "\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
Daniel Veillard81273902003-09-30 00:43:48 +00003069#ifdef LIBXML_READER_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003070 fprintf(f, "\t--stream : use the streaming interface to process very large files\n");
3071 fprintf(f, "\t--walker : create a reader and walk though the resulting doc\n");
Daniel Veillard81273902003-09-30 00:43:48 +00003072#endif /* LIBXML_READER_ENABLED */
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003073#ifdef LIBXML_PATTERN_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003074 fprintf(f, "\t--pattern pattern_value : test the pattern support\n");
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003075#endif
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003076 fprintf(f, "\t--chkregister : verify the node registration code\n");
Daniel Veillardef4d3bc2003-02-07 12:38:22 +00003077#ifdef LIBXML_SCHEMAS_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003078 fprintf(f, "\t--relaxng schema : do RelaxNG validation against the schema\n");
3079 fprintf(f, "\t--schema schema : do validation against the WXS schema\n");
Daniel Veillard71531f32003-02-05 13:19:53 +00003080#endif
Daniel Veillarde70375c2005-07-30 21:09:12 +00003081#ifdef LIBXML_SCHEMATRON_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003082 fprintf(f, "\t--schematron schema : do validation against a schematron\n");
Daniel Veillarde70375c2005-07-30 21:09:12 +00003083#endif
Daniel Veillard971771e2005-07-09 17:32:57 +00003084#ifdef LIBXML_SAX1_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003085 fprintf(f, "\t--sax1: use the old SAX1 interfaces for processing\n");
Daniel Veillard971771e2005-07-09 17:32:57 +00003086#endif
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003087 fprintf(f, "\t--sax: do not build a tree but work just at the SAX level\n");
3088 fprintf(f, "\t--oldxml10: use XML-1.0 parsing rules before the 5th edition\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003089#ifdef LIBXML_XPATH_ENABLED
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003090 fprintf(f, "\t--xpath expr: evaluate the XPath expression, imply --noout\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003091#endif
Daniel Veillard971771e2005-07-09 17:32:57 +00003092
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003093 fprintf(f, "\nLibxml project home page: http://xmlsoft.org/\n");
3094 fprintf(f, "To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003095}
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003096
3097static void registerNode(xmlNodePtr node)
3098{
3099 node->_private = malloc(sizeof(long));
Daniel Veillarde71dce12013-07-11 15:41:22 +08003100 if (node->_private == NULL) {
3101 fprintf(stderr, "Out of memory in xmllint:registerNode()\n");
3102 exit(XMLLINT_ERR_MEM);
3103 }
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003104 *(long*)node->_private = (long) 0x81726354;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003105 nbregister++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003106}
3107
3108static void deregisterNode(xmlNodePtr node)
3109{
3110 assert(node->_private != NULL);
3111 assert(*(long*)node->_private == (long) 0x81726354);
3112 free(node->_private);
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003113 nbregister--;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003114}
3115
Daniel Veillard4a6845d2001-01-03 13:32:39 +00003116int
3117main(int argc, char **argv) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00003118 int i, acount;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003119 int files = 0;
Daniel Veillard845cce42002-01-09 11:51:37 +00003120 int version = 0;
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00003121 const char* indent;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003122
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003123 if (argc <= 1) {
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003124 usage(stderr, argv[0]);
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003125 return(1);
3126 }
Daniel Veillardbe803962000-06-28 23:40:59 +00003127 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003128 for (i = 1; i < argc ; i++) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003129 if (!strcmp(argv[i], "-"))
3130 break;
3131
3132 if (argv[i][0] != '-')
3133 continue;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003134 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
3135 debug++;
Daniel Veillard56ada1d2003-01-07 11:17:25 +00003136 else
3137#ifdef LIBXML_DEBUG_ENABLED
3138 if ((!strcmp(argv[i], "-shell")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003139 (!strcmp(argv[i], "--shell"))) {
3140 shell++;
3141 noout = 1;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003142 } else
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003143#endif
Daniel Veillard652327a2003-09-29 18:02:38 +00003144#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003145 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
3146 copy++;
Daniel Veillard652327a2003-09-29 18:02:38 +00003147 else
3148#endif /* LIBXML_TREE_ENABLED */
3149 if ((!strcmp(argv[i], "-recover")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003150 (!strcmp(argv[i], "--recover"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003151 recovery++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003152 options |= XML_PARSE_RECOVER;
Daniel Veillard8915c152008-08-26 13:05:34 +00003153 } else if ((!strcmp(argv[i], "-huge")) ||
3154 (!strcmp(argv[i], "--huge"))) {
3155 options |= XML_PARSE_HUGE;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003156 } else if ((!strcmp(argv[i], "-noent")) ||
3157 (!strcmp(argv[i], "--noent"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003158 noent++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003159 options |= XML_PARSE_NOENT;
Daniel Veillardc62efc82011-05-16 16:03:50 +08003160 } else if ((!strcmp(argv[i], "-noenc")) ||
3161 (!strcmp(argv[i], "--noenc"))) {
3162 noenc++;
3163 options |= XML_PARSE_IGNORE_ENC;
Daniel Veillarddca8cc72003-09-26 13:53:14 +00003164 } else if ((!strcmp(argv[i], "-nsclean")) ||
3165 (!strcmp(argv[i], "--nsclean"))) {
3166 options |= XML_PARSE_NSCLEAN;
3167 } else if ((!strcmp(argv[i], "-nocdata")) ||
3168 (!strcmp(argv[i], "--nocdata"))) {
3169 options |= XML_PARSE_NOCDATA;
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003170 } else if ((!strcmp(argv[i], "-nodict")) ||
3171 (!strcmp(argv[i], "--nodict"))) {
3172 options |= XML_PARSE_NODICT;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003173 } else if ((!strcmp(argv[i], "-version")) ||
Daniel Veillard845cce42002-01-09 11:51:37 +00003174 (!strcmp(argv[i], "--version"))) {
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00003175 showVersion(argv[0]);
Daniel Veillard845cce42002-01-09 11:51:37 +00003176 version = 1;
3177 } else if ((!strcmp(argv[i], "-noout")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003178 (!strcmp(argv[i], "--noout")))
3179 noout++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003180#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003181 else if ((!strcmp(argv[i], "-o")) ||
3182 (!strcmp(argv[i], "-output")) ||
3183 (!strcmp(argv[i], "--output"))) {
3184 i++;
Daniel Veillard6e4f1c02002-04-09 09:55:20 +00003185 output = argv[i];
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003186 }
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003187#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003188 else if ((!strcmp(argv[i], "-htmlout")) ||
3189 (!strcmp(argv[i], "--htmlout")))
3190 htmlout++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003191 else if ((!strcmp(argv[i], "-nowrap")) ||
3192 (!strcmp(argv[i], "--nowrap")))
3193 nowrap++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003194#ifdef LIBXML_HTML_ENABLED
3195 else if ((!strcmp(argv[i], "-html")) ||
3196 (!strcmp(argv[i], "--html"))) {
3197 html++;
3198 }
Daniel Veillard42fd4122003-11-04 08:47:48 +00003199 else if ((!strcmp(argv[i], "-xmlout")) ||
3200 (!strcmp(argv[i], "--xmlout"))) {
3201 xmlout++;
Daniel Veillardf1121c42010-07-26 14:02:42 +02003202 } else if ((!strcmp(argv[i], "-nodefdtd")) ||
3203 (!strcmp(argv[i], "--nodefdtd"))) {
3204 nodefdtd++;
3205 options |= HTML_PARSE_NODEFDTD;
Daniel Veillard42fd4122003-11-04 08:47:48 +00003206 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003207#endif /* LIBXML_HTML_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003208 else if ((!strcmp(argv[i], "-loaddtd")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003209 (!strcmp(argv[i], "--loaddtd"))) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003210 loaddtd++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003211 options |= XML_PARSE_DTDLOAD;
3212 } else if ((!strcmp(argv[i], "-dtdattr")) ||
Daniel Veillard48da9102001-08-07 01:10:10 +00003213 (!strcmp(argv[i], "--dtdattr"))) {
3214 loaddtd++;
3215 dtdattrs++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003216 options |= XML_PARSE_DTDATTR;
Daniel Veillard4432df22003-09-28 18:58:27 +00003217 }
3218#ifdef LIBXML_VALID_ENABLED
3219 else if ((!strcmp(argv[i], "-valid")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003220 (!strcmp(argv[i], "--valid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003221 valid++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003222 options |= XML_PARSE_DTDVALID;
3223 } else if ((!strcmp(argv[i], "-postvalid")) ||
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003224 (!strcmp(argv[i], "--postvalid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003225 postvalid++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003226 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003227 options |= XML_PARSE_DTDLOAD;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003228 } else if ((!strcmp(argv[i], "-dtdvalid")) ||
Daniel Veillardcd429612000-10-11 15:57:05 +00003229 (!strcmp(argv[i], "--dtdvalid"))) {
3230 i++;
3231 dtdvalid = argv[i];
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003232 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003233 options |= XML_PARSE_DTDLOAD;
Daniel Veillard66f68e72003-08-18 16:39:51 +00003234 } else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3235 (!strcmp(argv[i], "--dtdvalidfpi"))) {
3236 i++;
3237 dtdvalidfpi = argv[i];
3238 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003239 options |= XML_PARSE_DTDLOAD;
Daniel Veillardcd429612000-10-11 15:57:05 +00003240 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003241#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard29e43992001-12-13 22:21:58 +00003242 else if ((!strcmp(argv[i], "-dropdtd")) ||
3243 (!strcmp(argv[i], "--dropdtd")))
3244 dropdtd++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003245 else if ((!strcmp(argv[i], "-insert")) ||
3246 (!strcmp(argv[i], "--insert")))
3247 insert++;
Daniel Veillard48b2f892001-02-25 16:11:03 +00003248 else if ((!strcmp(argv[i], "-timing")) ||
3249 (!strcmp(argv[i], "--timing")))
3250 timing++;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00003251 else if ((!strcmp(argv[i], "-auto")) ||
3252 (!strcmp(argv[i], "--auto")))
3253 generate++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003254 else if ((!strcmp(argv[i], "-repeat")) ||
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00003255 (!strcmp(argv[i], "--repeat"))) {
3256 if (repeat)
3257 repeat *= 10;
3258 else
3259 repeat = 100;
Daniel Veillard73b013f2003-09-30 12:36:01 +00003260 }
3261#ifdef LIBXML_PUSH_ENABLED
3262 else if ((!strcmp(argv[i], "-push")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003263 (!strcmp(argv[i], "--push")))
3264 push++;
Daniel Veillard1abd2212012-10-25 15:37:50 +08003265 else if ((!strcmp(argv[i], "-pushsmall")) ||
3266 (!strcmp(argv[i], "--pushsmall"))) {
3267 push++;
3268 pushsize = 10;
3269 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00003270#endif /* LIBXML_PUSH_ENABLED */
Daniel Richard G5706b6d2012-08-06 11:32:54 +08003271#ifdef HAVE_MMAP
Daniel Veillard46e370e2000-07-21 20:32:03 +00003272 else if ((!strcmp(argv[i], "-memory")) ||
3273 (!strcmp(argv[i], "--memory")))
3274 memory++;
3275#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +00003276 else if ((!strcmp(argv[i], "-testIO")) ||
3277 (!strcmp(argv[i], "--testIO")))
3278 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003279#ifdef LIBXML_XINCLUDE_ENABLED
3280 else if ((!strcmp(argv[i], "-xinclude")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003281 (!strcmp(argv[i], "--xinclude"))) {
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003282 xinclude++;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003283 options |= XML_PARSE_XINCLUDE;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003284 }
Daniel Veillardc14c3892004-08-16 12:34:50 +00003285 else if ((!strcmp(argv[i], "-noxincludenode")) ||
3286 (!strcmp(argv[i], "--noxincludenode"))) {
3287 xinclude++;
3288 options |= XML_PARSE_XINCLUDE;
3289 options |= XML_PARSE_NOXINCNODE;
3290 }
Daniel Veillard54bd29b2008-08-26 07:26:55 +00003291 else if ((!strcmp(argv[i], "-nofixup-base-uris")) ||
3292 (!strcmp(argv[i], "--nofixup-base-uris"))) {
3293 xinclude++;
3294 options |= XML_PARSE_XINCLUDE;
3295 options |= XML_PARSE_NOBASEFIX;
3296 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003297#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003298#ifdef LIBXML_OUTPUT_ENABLED
Nick Wellnhofercb5541c2017-11-13 17:08:38 +01003299#ifdef LIBXML_ZLIB_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003300 else if ((!strcmp(argv[i], "-compress")) ||
3301 (!strcmp(argv[i], "--compress"))) {
3302 compress++;
3303 xmlSetCompressMode(9);
3304 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003305#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003306#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003307 else if ((!strcmp(argv[i], "-nowarning")) ||
3308 (!strcmp(argv[i], "--nowarning"))) {
3309 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003310 xmlPedanticParserDefault(0);
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003311 options |= XML_PARSE_NOWARNING;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003312 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003313 else if ((!strcmp(argv[i], "-pedantic")) ||
3314 (!strcmp(argv[i], "--pedantic"))) {
3315 xmlGetWarningsDefaultValue = 1;
3316 xmlPedanticParserDefault(1);
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003317 options |= XML_PARSE_PEDANTIC;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003318 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00003319#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003320 else if ((!strcmp(argv[i], "-debugent")) ||
3321 (!strcmp(argv[i], "--debugent"))) {
3322 debugent++;
3323 xmlParserDebugEntities = 1;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003324 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00003325#endif
Daniel Veillard25048d82004-08-14 22:37:54 +00003326#ifdef LIBXML_C14N_ENABLED
3327 else if ((!strcmp(argv[i], "-c14n")) ||
3328 (!strcmp(argv[i], "--c14n"))) {
3329 canonical++;
3330 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003331 }
Aleksey Sanin83868242009-07-09 10:26:22 +02003332 else if ((!strcmp(argv[i], "-c14n11")) ||
3333 (!strcmp(argv[i], "--c14n11"))) {
3334 canonical_11++;
3335 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003336 }
Aleksey Sanin2650df12005-06-06 17:16:50 +00003337 else if ((!strcmp(argv[i], "-exc-c14n")) ||
3338 (!strcmp(argv[i], "--exc-c14n"))) {
3339 exc_canonical++;
3340 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003341 }
Daniel Veillard25048d82004-08-14 22:37:54 +00003342#endif
Daniel Veillard81418e32001-05-22 15:08:55 +00003343#ifdef LIBXML_CATALOG_ENABLED
3344 else if ((!strcmp(argv[i], "-catalogs")) ||
3345 (!strcmp(argv[i], "--catalogs"))) {
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003346 catalogs++;
3347 } else if ((!strcmp(argv[i], "-nocatalogs")) ||
3348 (!strcmp(argv[i], "--nocatalogs"))) {
3349 nocatalogs++;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003350 }
Daniel Veillard81418e32001-05-22 15:08:55 +00003351#endif
Daniel Veillardbe803962000-06-28 23:40:59 +00003352 else if ((!strcmp(argv[i], "-encode")) ||
3353 (!strcmp(argv[i], "--encode"))) {
3354 i++;
3355 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003356 /*
3357 * OK it's for testing purposes
3358 */
3359 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +00003360 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003361 else if ((!strcmp(argv[i], "-noblanks")) ||
3362 (!strcmp(argv[i], "--noblanks"))) {
Daniel Veillardf933c892012-09-07 19:32:12 +08003363 noblanks++;
3364 xmlKeepBlanksDefault(0);
3365 options |= XML_PARSE_NOBLANKS;
Daniel Veillard90493a92001-08-14 14:12:47 +00003366 }
Daniel Veillard87076042004-05-03 22:54:49 +00003367 else if ((!strcmp(argv[i], "-maxmem")) ||
3368 (!strcmp(argv[i], "--maxmem"))) {
3369 i++;
3370 if (sscanf(argv[i], "%d", &maxmem) == 1) {
3371 xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc,
3372 myStrdupFunc);
3373 } else {
3374 maxmem = 0;
3375 }
3376 }
Daniel Veillard90493a92001-08-14 14:12:47 +00003377 else if ((!strcmp(argv[i], "-format")) ||
3378 (!strcmp(argv[i], "--format"))) {
3379 noblanks++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003380#ifdef LIBXML_OUTPUT_ENABLED
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01003381 format = 1;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003382#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard90493a92001-08-14 14:12:47 +00003383 xmlKeepBlanksDefault(0);
Daniel Veillard7704fb12003-01-03 16:19:51 +00003384 }
Adam Spraggd2e62312010-11-03 15:33:40 +01003385 else if ((!strcmp(argv[i], "-pretty")) ||
3386 (!strcmp(argv[i], "--pretty"))) {
3387 i++;
3388#ifdef LIBXML_OUTPUT_ENABLED
Tim Galeckas2205ff42013-08-29 16:44:33 +08003389 if (argv[i] != NULL) {
3390 format = atoi(argv[i]);
3391 if (format == 1) {
3392 noblanks++;
3393 xmlKeepBlanksDefault(0);
3394 }
3395 }
Brandon Slack0c7109c2012-05-11 10:50:59 +08003396#endif /* LIBXML_OUTPUT_ENABLED */
Adam Spraggd2e62312010-11-03 15:33:40 +01003397 }
Daniel Veillard81273902003-09-30 00:43:48 +00003398#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003399 else if ((!strcmp(argv[i], "-stream")) ||
3400 (!strcmp(argv[i], "--stream"))) {
3401 stream++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003402 }
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003403 else if ((!strcmp(argv[i], "-walker")) ||
3404 (!strcmp(argv[i], "--walker"))) {
3405 walker++;
3406 noout++;
3407 }
Daniel Veillard81273902003-09-30 00:43:48 +00003408#endif /* LIBXML_READER_ENABLED */
3409#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +00003410 else if ((!strcmp(argv[i], "-sax1")) ||
3411 (!strcmp(argv[i], "--sax1"))) {
Daniel Veillard023d0ba2009-07-29 11:34:50 +02003412 sax1++;
3413 options |= XML_PARSE_SAX1;
Daniel Veillard07cb8222003-09-10 10:51:05 +00003414 }
Daniel Veillard81273902003-09-30 00:43:48 +00003415#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003416 else if ((!strcmp(argv[i], "-sax")) ||
3417 (!strcmp(argv[i], "--sax"))) {
Daniel Veillard023d0ba2009-07-29 11:34:50 +02003418 sax++;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003419 }
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003420 else if ((!strcmp(argv[i], "-chkregister")) ||
3421 (!strcmp(argv[i], "--chkregister"))) {
Daniel Veillard023d0ba2009-07-29 11:34:50 +02003422 chkregister++;
Daniel Veillard71531f32003-02-05 13:19:53 +00003423#ifdef LIBXML_SCHEMAS_ENABLED
3424 } else if ((!strcmp(argv[i], "-relaxng")) ||
3425 (!strcmp(argv[i], "--relaxng"))) {
3426 i++;
3427 relaxng = argv[i];
3428 noent++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003429 options |= XML_PARSE_NOENT;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003430 } else if ((!strcmp(argv[i], "-schema")) ||
3431 (!strcmp(argv[i], "--schema"))) {
3432 i++;
3433 schema = argv[i];
3434 noent++;
Daniel Veillard71531f32003-02-05 13:19:53 +00003435#endif
Daniel Veillardd4501d72005-07-24 14:27:16 +00003436#ifdef LIBXML_SCHEMATRON_ENABLED
3437 } else if ((!strcmp(argv[i], "-schematron")) ||
3438 (!strcmp(argv[i], "--schematron"))) {
3439 i++;
3440 schematron = argv[i];
3441 noent++;
3442#endif
Daniel Veillarde8b09e42003-05-13 22:14:13 +00003443 } else if ((!strcmp(argv[i], "-nonet")) ||
3444 (!strcmp(argv[i], "--nonet"))) {
Daniel Veillard61b93382003-11-03 14:28:31 +00003445 options |= XML_PARSE_NONET;
Daniel Veillard968d6432006-04-25 16:17:53 +00003446 xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
Daniel Veillard8874b942005-08-25 13:19:21 +00003447 } else if ((!strcmp(argv[i], "-nocompact")) ||
3448 (!strcmp(argv[i], "--nocompact"))) {
3449 options &= ~XML_PARSE_COMPACT;
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003450 } else if ((!strcmp(argv[i], "-load-trace")) ||
3451 (!strcmp(argv[i], "--load-trace"))) {
3452 load_trace++;
3453 } else if ((!strcmp(argv[i], "-path")) ||
3454 (!strcmp(argv[i], "--path"))) {
3455 i++;
3456 parsePath(BAD_CAST argv[i]);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003457#ifdef LIBXML_PATTERN_ENABLED
3458 } else if ((!strcmp(argv[i], "-pattern")) ||
3459 (!strcmp(argv[i], "--pattern"))) {
3460 i++;
3461 pattern = argv[i];
3462#endif
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003463#ifdef LIBXML_XPATH_ENABLED
3464 } else if ((!strcmp(argv[i], "-xpath")) ||
3465 (!strcmp(argv[i], "--xpath"))) {
3466 i++;
3467 noout++;
3468 xpathquery = argv[i];
3469#endif
Daniel Veillard7e5c3f42008-07-29 16:12:31 +00003470 } else if ((!strcmp(argv[i], "-oldxml10")) ||
3471 (!strcmp(argv[i], "--oldxml10"))) {
3472 oldxml10++;
3473 options |= XML_PARSE_OLD10;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003474 } else {
3475 fprintf(stderr, "Unknown option %s\n", argv[i]);
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003476 usage(stderr, argv[0]);
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003477 return(1);
3478 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003479 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003480
3481#ifdef LIBXML_CATALOG_ENABLED
3482 if (nocatalogs == 0) {
3483 if (catalogs) {
3484 const char *catal;
3485
3486 catal = getenv("SGML_CATALOG_FILES");
Daniel Veillard6c5f9d12001-08-25 13:33:14 +00003487 if (catal != NULL) {
3488 xmlLoadCatalogs(catal);
3489 } else {
3490 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
3491 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003492 }
3493 }
3494#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003495
Daniel Veillard81273902003-09-30 00:43:48 +00003496#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +00003497 if (sax1)
3498 xmlSAXDefaultVersion(1);
3499 else
3500 xmlSAXDefaultVersion(2);
Daniel Veillard81273902003-09-30 00:43:48 +00003501#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillard07cb8222003-09-10 10:51:05 +00003502
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003503 if (chkregister) {
3504 xmlRegisterNodeDefault(registerNode);
3505 xmlDeregisterNodeDefault(deregisterNode);
3506 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02003507
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00003508 indent = getenv("XMLLINT_INDENT");
3509 if(indent != NULL) {
3510 xmlTreeIndentString = indent;
3511 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02003512
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003513
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003514 defaultEntityLoader = xmlGetExternalEntityLoader();
3515 xmlSetExternalEntityLoader(xmllintExternalEntityLoader);
3516
Daniel Veillardd9bad132001-07-23 19:39:43 +00003517 xmlLineNumbersDefault(1);
Daniel Veillard48da9102001-08-07 01:10:10 +00003518 if (loaddtd != 0)
3519 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
3520 if (dtdattrs)
3521 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003522 if (noent != 0) xmlSubstituteEntitiesDefault(1);
Daniel Veillard4432df22003-09-28 18:58:27 +00003523#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003524 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
Daniel Veillard4432df22003-09-28 18:58:27 +00003525#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003526 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003527 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003528 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003529 xmlGenericError(xmlGenericErrorContext,
3530 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
3531 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003532 "<html><head><title>%s output</title></head>\n",
3533 argv[0]);
Daniel Veillardf1edb102009-08-10 14:43:18 +02003534 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003535 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
3536 argv[0]);
3537 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003538
Daniel Veillardd4501d72005-07-24 14:27:16 +00003539#ifdef LIBXML_SCHEMATRON_ENABLED
3540 if ((schematron != NULL) && (sax == 0)
3541#ifdef LIBXML_READER_ENABLED
3542 && (stream == 0)
3543#endif /* LIBXML_READER_ENABLED */
3544 ) {
3545 xmlSchematronParserCtxtPtr ctxt;
3546
3547 /* forces loading the DTDs */
Daniel Veillardf1edb102009-08-10 14:43:18 +02003548 xmlLoadExtDtdDefaultValue |= 1;
Daniel Veillardd4501d72005-07-24 14:27:16 +00003549 options |= XML_PARSE_DTDLOAD;
3550 if (timing) {
3551 startTimer();
3552 }
3553 ctxt = xmlSchematronNewParserCtxt(schematron);
3554#if 0
3555 xmlSchematronSetParserErrors(ctxt,
3556 (xmlSchematronValidityErrorFunc) fprintf,
3557 (xmlSchematronValidityWarningFunc) fprintf,
3558 stderr);
3559#endif
3560 wxschematron = xmlSchematronParse(ctxt);
3561 if (wxschematron == NULL) {
3562 xmlGenericError(xmlGenericErrorContext,
3563 "Schematron schema %s failed to compile\n", schematron);
3564 progresult = XMLLINT_ERR_SCHEMACOMP;
3565 schematron = NULL;
3566 }
3567 xmlSchematronFreeParserCtxt(ctxt);
3568 if (timing) {
3569 endTimer("Compiling the schemas");
3570 }
3571 }
3572#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00003573#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003574 if ((relaxng != NULL) && (sax == 0)
Daniel Veillard81273902003-09-30 00:43:48 +00003575#ifdef LIBXML_READER_ENABLED
3576 && (stream == 0)
3577#endif /* LIBXML_READER_ENABLED */
3578 ) {
Daniel Veillard71531f32003-02-05 13:19:53 +00003579 xmlRelaxNGParserCtxtPtr ctxt;
3580
Daniel Veillardce192eb2003-04-16 15:58:05 +00003581 /* forces loading the DTDs */
Daniel Veillardf1edb102009-08-10 14:43:18 +02003582 xmlLoadExtDtdDefaultValue |= 1;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003583 options |= XML_PARSE_DTDLOAD;
Daniel Veillard42f12e92003-03-07 18:32:59 +00003584 if (timing) {
3585 startTimer();
3586 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003587 ctxt = xmlRelaxNGNewParserCtxt(relaxng);
3588 xmlRelaxNGSetParserErrors(ctxt,
3589 (xmlRelaxNGValidityErrorFunc) fprintf,
3590 (xmlRelaxNGValidityWarningFunc) fprintf,
3591 stderr);
3592 relaxngschemas = xmlRelaxNGParse(ctxt);
Daniel Veillardce192eb2003-04-16 15:58:05 +00003593 if (relaxngschemas == NULL) {
3594 xmlGenericError(xmlGenericErrorContext,
3595 "Relax-NG schema %s failed to compile\n", relaxng);
William M. Brack8304d872004-06-08 13:29:32 +00003596 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillardce192eb2003-04-16 15:58:05 +00003597 relaxng = NULL;
3598 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003599 xmlRelaxNGFreeParserCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00003600 if (timing) {
3601 endTimer("Compiling the schemas");
3602 }
Daniel Veillardebe25d42004-03-25 09:35:49 +00003603 } else if ((schema != NULL)
3604#ifdef LIBXML_READER_ENABLED
Daniel Veillardf10ae122005-07-10 19:03:16 +00003605 && (stream == 0)
Daniel Veillardebe25d42004-03-25 09:35:49 +00003606#endif
3607 ) {
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003608 xmlSchemaParserCtxtPtr ctxt;
3609
3610 if (timing) {
3611 startTimer();
3612 }
3613 ctxt = xmlSchemaNewParserCtxt(schema);
3614 xmlSchemaSetParserErrors(ctxt,
3615 (xmlSchemaValidityErrorFunc) fprintf,
3616 (xmlSchemaValidityWarningFunc) fprintf,
3617 stderr);
3618 wxschemas = xmlSchemaParse(ctxt);
3619 if (wxschemas == NULL) {
3620 xmlGenericError(xmlGenericErrorContext,
3621 "WXS schema %s failed to compile\n", schema);
William M. Brack8304d872004-06-08 13:29:32 +00003622 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003623 schema = NULL;
3624 }
3625 xmlSchemaFreeParserCtxt(ctxt);
3626 if (timing) {
3627 endTimer("Compiling the schemas");
3628 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003629 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003630#endif /* LIBXML_SCHEMAS_ENABLED */
3631#ifdef LIBXML_PATTERN_ENABLED
Daniel Veillard39e5c892005-07-03 22:48:50 +00003632 if ((pattern != NULL)
Daniel Veillardc9352532005-07-04 14:25:34 +00003633#ifdef LIBXML_READER_ENABLED
Daniel Veillard39e5c892005-07-03 22:48:50 +00003634 && (walker == 0)
3635#endif
3636 ) {
Daniel Veillardffa7b7e2003-12-05 16:10:21 +00003637 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003638 if (patternc == NULL) {
3639 xmlGenericError(xmlGenericErrorContext,
3640 "Pattern %s failed to compile\n", pattern);
William M. Brack8304d872004-06-08 13:29:32 +00003641 progresult = XMLLINT_ERR_SCHEMAPAT;
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003642 pattern = NULL;
3643 }
3644 }
3645#endif /* LIBXML_PATTERN_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003646 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +00003647 if ((!strcmp(argv[i], "-encode")) ||
3648 (!strcmp(argv[i], "--encode"))) {
3649 i++;
3650 continue;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003651 } else if ((!strcmp(argv[i], "-o")) ||
3652 (!strcmp(argv[i], "-output")) ||
3653 (!strcmp(argv[i], "--output"))) {
3654 i++;
3655 continue;
Daniel Veillardbe803962000-06-28 23:40:59 +00003656 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003657#ifdef LIBXML_VALID_ENABLED
Daniel Veillardcd429612000-10-11 15:57:05 +00003658 if ((!strcmp(argv[i], "-dtdvalid")) ||
3659 (!strcmp(argv[i], "--dtdvalid"))) {
3660 i++;
3661 continue;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003662 }
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003663 if ((!strcmp(argv[i], "-path")) ||
3664 (!strcmp(argv[i], "--path"))) {
3665 i++;
3666 continue;
Daniel Veillardcd429612000-10-11 15:57:05 +00003667 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00003668 if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3669 (!strcmp(argv[i], "--dtdvalidfpi"))) {
3670 i++;
3671 continue;
3672 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003673#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard71531f32003-02-05 13:19:53 +00003674 if ((!strcmp(argv[i], "-relaxng")) ||
3675 (!strcmp(argv[i], "--relaxng"))) {
3676 i++;
3677 continue;
3678 }
Daniel Veillard87076042004-05-03 22:54:49 +00003679 if ((!strcmp(argv[i], "-maxmem")) ||
3680 (!strcmp(argv[i], "--maxmem"))) {
3681 i++;
3682 continue;
3683 }
Adam Spraggd2e62312010-11-03 15:33:40 +01003684 if ((!strcmp(argv[i], "-pretty")) ||
3685 (!strcmp(argv[i], "--pretty"))) {
3686 i++;
3687 continue;
3688 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003689 if ((!strcmp(argv[i], "-schema")) ||
3690 (!strcmp(argv[i], "--schema"))) {
3691 i++;
3692 continue;
3693 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00003694 if ((!strcmp(argv[i], "-schematron")) ||
3695 (!strcmp(argv[i], "--schematron"))) {
3696 i++;
3697 continue;
3698 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003699#ifdef LIBXML_PATTERN_ENABLED
3700 if ((!strcmp(argv[i], "-pattern")) ||
3701 (!strcmp(argv[i], "--pattern"))) {
3702 i++;
3703 continue;
3704 }
3705#endif
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003706#ifdef LIBXML_XPATH_ENABLED
3707 if ((!strcmp(argv[i], "-xpath")) ||
3708 (!strcmp(argv[i], "--xpath"))) {
3709 i++;
3710 continue;
3711 }
3712#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00003713 if ((timing) && (repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00003714 startTimer();
Daniel Veillardcbaf3992001-12-31 16:16:02 +00003715 /* Remember file names. "-" means stdin. <sven@zen.org> */
Daniel Veillard4a6845d2001-01-03 13:32:39 +00003716 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003717 if (repeat) {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003718 xmlParserCtxtPtr ctxt = NULL;
3719
3720 for (acount = 0;acount < repeat;acount++) {
Daniel Veillard81273902003-09-30 00:43:48 +00003721#ifdef LIBXML_READER_ENABLED
Daniel Veillard198c1bf2003-10-20 17:07:41 +00003722 if (stream != 0) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00003723 streamFile(argv[i]);
Daniel Veillard198c1bf2003-10-20 17:07:41 +00003724 } else {
Daniel Veillard81273902003-09-30 00:43:48 +00003725#endif /* LIBXML_READER_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003726 if (sax) {
3727 testSAX(argv[i]);
3728 } else {
3729 if (ctxt == NULL)
3730 ctxt = xmlNewParserCtxt();
3731 parseAndPrintFile(argv[i], ctxt);
3732 }
Daniel Veillard81273902003-09-30 00:43:48 +00003733#ifdef LIBXML_READER_ENABLED
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003734 }
Daniel Veillard81273902003-09-30 00:43:48 +00003735#endif /* LIBXML_READER_ENABLED */
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003736 }
3737 if (ctxt != NULL)
3738 xmlFreeParserCtxt(ctxt);
Daniel Veillard7704fb12003-01-03 16:19:51 +00003739 } else {
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003740 nbregister = 0;
3741
Daniel Veillard81273902003-09-30 00:43:48 +00003742#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003743 if (stream != 0)
3744 streamFile(argv[i]);
3745 else
Daniel Veillard81273902003-09-30 00:43:48 +00003746#endif /* LIBXML_READER_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003747 if (sax) {
3748 testSAX(argv[i]);
3749 } else {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003750 parseAndPrintFile(argv[i], NULL);
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003751 }
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003752
3753 if ((chkregister) && (nbregister != 0)) {
3754 fprintf(stderr, "Registration count off: %d\n", nbregister);
William M. Brack8304d872004-06-08 13:29:32 +00003755 progresult = XMLLINT_ERR_RDREGIS;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003756 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00003757 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003758 files ++;
Daniel Veillarda7866932001-12-04 13:14:44 +00003759 if ((timing) && (repeat)) {
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00003760 endTimer("%d iterations", repeat);
Daniel Veillarda7866932001-12-04 13:14:44 +00003761 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00003762 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003763 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02003764 if (generate)
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003765 parseAndPrintFile(NULL, NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003766 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003767 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003768 }
Daniel Veillard845cce42002-01-09 11:51:37 +00003769 if ((files == 0) && (!generate) && (version == 0)) {
Nick Wellnhoferf4353652017-06-20 16:19:33 +02003770 usage(stderr, argv[0]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003771 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00003772#ifdef LIBXML_SCHEMATRON_ENABLED
3773 if (wxschematron != NULL)
3774 xmlSchematronFree(wxschematron);
3775#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00003776#ifdef LIBXML_SCHEMAS_ENABLED
3777 if (relaxngschemas != NULL)
3778 xmlRelaxNGFree(relaxngschemas);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003779 if (wxschemas != NULL)
3780 xmlSchemaFree(wxschemas);
Daniel Veillard71531f32003-02-05 13:19:53 +00003781 xmlRelaxNGCleanupTypes();
3782#endif
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003783#ifdef LIBXML_PATTERN_ENABLED
3784 if (patternc != NULL)
3785 xmlFreePattern(patternc);
3786#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003787 xmlCleanupParser();
3788 xmlMemoryDump();
3789
Daniel Veillardf7cd4812001-02-23 18:44:52 +00003790 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003791}
Daniel Veillard88a172f2000-08-04 18:23:10 +00003792