blob: d9368c1dd8f7286296c13754ecdb3d9504cf9ba5 [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 Veillard3c5ed912002-01-08 10:36:16 +000015#if defined (_WIN32) && !defined(__CYGWIN__)
Daniel Veillard07cb8222003-09-10 10:51:05 +000016#if defined (_MSC_VER) || defined(__BORLANDC__)
Daniel Veillard2d90de42001-04-16 17:46:18 +000017#include <winsock2.h>
18#pragma comment(lib, "ws2_32.lib")
19#define gettimeofday(p1,p2)
20#endif /* _MSC_VER */
Igor Zlatkovic19b87642003-08-28 12:32:04 +000021#endif /* _WIN32 */
22
Daniel Veillarded472f32001-12-13 08:48:14 +000023#ifdef HAVE_SYS_TIME_H
Daniel Veillard48b2f892001-02-25 16:11:03 +000024#include <sys/time.h>
Daniel Veillarded472f32001-12-13 08:48:14 +000025#endif
Daniel Veillard01db67c2001-12-18 07:09:59 +000026#ifdef HAVE_TIME_H
27#include <time.h>
28#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +000029
Daniel Veillard1638a472003-08-14 01:23:25 +000030#ifdef __MINGW32__
31#define _WINSOCKAPI_
32#include <wsockcompat.h>
33#include <winsock2.h>
Daniel Veillardc284c642005-03-31 10:24:24 +000034#undef XML_SOCKLEN_T
35#define XML_SOCKLEN_T unsigned int
Daniel Veillard1638a472003-08-14 01:23:25 +000036#endif
37
Daniel Veillard90bc3712002-03-07 15:12:58 +000038#ifdef HAVE_SYS_TIMEB_H
39#include <sys/timeb.h>
40#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000041
42#ifdef HAVE_SYS_TYPES_H
43#include <sys/types.h>
44#endif
45#ifdef HAVE_SYS_STAT_H
46#include <sys/stat.h>
47#endif
48#ifdef HAVE_FCNTL_H
49#include <fcntl.h>
50#endif
51#ifdef HAVE_UNISTD_H
52#include <unistd.h>
53#endif
Daniel Veillard46e370e2000-07-21 20:32:03 +000054#ifdef HAVE_SYS_MMAN_H
55#include <sys/mman.h>
Daniel Veillard87b95392000-08-12 21:12:04 +000056/* seems needed for Solaris */
57#ifndef MAP_FAILED
58#define MAP_FAILED ((void *) -1)
59#endif
Daniel Veillard46e370e2000-07-21 20:32:03 +000060#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000061#ifdef HAVE_STDLIB_H
62#include <stdlib.h>
63#endif
64#ifdef HAVE_LIBREADLINE
65#include <readline/readline.h>
66#ifdef HAVE_LIBHISTORY
67#include <readline/history.h>
68#endif
69#endif
70
71#include <libxml/xmlmemory.h>
72#include <libxml/parser.h>
73#include <libxml/parserInternals.h>
74#include <libxml/HTMLparser.h>
75#include <libxml/HTMLtree.h>
76#include <libxml/tree.h>
77#include <libxml/xpath.h>
78#include <libxml/debugXML.h>
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +000079#include <libxml/xmlerror.h>
Daniel Veillard9e8bfae2000-11-06 16:43:11 +000080#ifdef LIBXML_XINCLUDE_ENABLED
81#include <libxml/xinclude.h>
82#endif
Daniel Veillard81418e32001-05-22 15:08:55 +000083#ifdef LIBXML_CATALOG_ENABLED
84#include <libxml/catalog.h>
85#endif
Daniel Veillard3c01b1d2001-10-17 15:58:35 +000086#include <libxml/globals.h>
Daniel Veillard7704fb12003-01-03 16:19:51 +000087#include <libxml/xmlreader.h>
Daniel Veillardd4501d72005-07-24 14:27:16 +000088#ifdef LIBXML_SCHEMATRON_ENABLED
89#include <libxml/schematron.h>
90#endif
Daniel Veillard71531f32003-02-05 13:19:53 +000091#ifdef LIBXML_SCHEMAS_ENABLED
92#include <libxml/relaxng.h>
Daniel Veillard75bb3bb2003-05-12 15:25:56 +000093#include <libxml/xmlschemas.h>
Daniel Veillard71531f32003-02-05 13:19:53 +000094#endif
Daniel Veillardb3de70c2003-12-02 22:32:15 +000095#ifdef LIBXML_PATTERN_ENABLED
96#include <libxml/pattern.h>
97#endif
Daniel Veillard6ebf3c42004-08-22 13:11:39 +000098#ifdef LIBXML_C14N_ENABLED
99#include <libxml/c14n.h>
100#endif
Daniel Veillarddab39b52006-10-16 23:22:10 +0000101#ifdef LIBXML_OUTPUT_ENABLED
102#include <libxml/xmlsave.h>
103#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000104
Daniel Veillard3be27512003-01-26 19:49:04 +0000105#ifndef XML_XML_DEFAULT_CATALOG
106#define XML_XML_DEFAULT_CATALOG "file:///etc/xml/catalog"
107#endif
108
William M. Brack8304d872004-06-08 13:29:32 +0000109typedef enum {
110 XMLLINT_RETURN_OK = 0, /* No error */
Daniel Veillard1934b0c2009-10-07 10:25:06 +0200111 XMLLINT_ERR_UNCLASS = 1, /* Unclassified */
112 XMLLINT_ERR_DTD = 2, /* Error in DTD */
113 XMLLINT_ERR_VALID = 3, /* Validation error */
114 XMLLINT_ERR_RDFILE = 4, /* CtxtReadFile error */
115 XMLLINT_ERR_SCHEMACOMP = 5, /* Schema compilation */
116 XMLLINT_ERR_OUT = 6, /* Error writing output */
117 XMLLINT_ERR_SCHEMAPAT = 7, /* Error in schema pattern */
118 XMLLINT_ERR_RDREGIS = 8, /* Error in Reader registration */
119 XMLLINT_ERR_MEM = 9, /* Out of memory error */
120 XMLLINT_ERR_XPATH = 10 /* XPath evaluation error */
William M. Brack8304d872004-06-08 13:29:32 +0000121} xmllintReturnCode;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000122#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000123static int shell = 0;
124static int debugent = 0;
125#endif
Daniel Veillard8326e732003-01-07 00:19:07 +0000126static int debug = 0;
Daniel Veillard87076042004-05-03 22:54:49 +0000127static int maxmem = 0;
Daniel Veillard652327a2003-09-29 18:02:38 +0000128#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000129static int copy = 0;
Daniel Veillard652327a2003-09-29 18:02:38 +0000130#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000131static int recovery = 0;
132static int noent = 0;
Daniel Veillardc62efc82011-05-16 16:03:50 +0800133static int noenc = 0;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +0000134static int noblanks = 0;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000135static int noout = 0;
136static int nowrap = 0;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +0000137#ifdef LIBXML_OUTPUT_ENABLED
138static int format = 0;
139static const char *output = NULL;
140static int compress = 0;
Daniel Veillarddab39b52006-10-16 23:22:10 +0000141static int oldout = 0;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +0000142#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard4432df22003-09-28 18:58:27 +0000143#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000144static int valid = 0;
145static int postvalid = 0;
Daniel Veillardcd429612000-10-11 15:57:05 +0000146static char * dtdvalid = NULL;
Daniel Veillard66f68e72003-08-18 16:39:51 +0000147static char * dtdvalidfpi = NULL;
Daniel Veillard4432df22003-09-28 18:58:27 +0000148#endif
Daniel Veillard71531f32003-02-05 13:19:53 +0000149#ifdef LIBXML_SCHEMAS_ENABLED
150static char * relaxng = NULL;
151static xmlRelaxNGPtr relaxngschemas = NULL;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +0000152static char * schema = NULL;
153static xmlSchemaPtr wxschemas = NULL;
Daniel Veillard71531f32003-02-05 13:19:53 +0000154#endif
Daniel Veillard8c6e6532005-09-08 21:39:47 +0000155#ifdef LIBXML_SCHEMATRON_ENABLED
Daniel Veillardd4501d72005-07-24 14:27:16 +0000156static char * schematron = NULL;
157static xmlSchematronPtr wxschematron = NULL;
158#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000159static int repeat = 0;
160static int insert = 0;
Daniel Veillard656ce942004-04-30 23:11:45 +0000161#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000162static int html = 0;
Daniel Veillard42fd4122003-11-04 08:47:48 +0000163static int xmlout = 0;
Daniel Veillard4432df22003-09-28 18:58:27 +0000164#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000165static int htmlout = 0;
Daniel Veillardf1121c42010-07-26 14:02:42 +0200166#if defined(LIBXML_HTML_ENABLED)
167static int nodefdtd = 0;
168#endif
Daniel Veillard73b013f2003-09-30 12:36:01 +0000169#ifdef LIBXML_PUSH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000170static int push = 0;
Daniel Veillard1abd2212012-10-25 15:37:50 +0800171static int pushsize = 4096;
Daniel Veillard73b013f2003-09-30 12:36:01 +0000172#endif /* LIBXML_PUSH_ENABLED */
Daniel Richard G5706b6d2012-08-06 11:32:54 +0800173#ifdef HAVE_MMAP
Daniel Veillard46e370e2000-07-21 20:32:03 +0000174static int memory = 0;
175#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +0000176static int testIO = 0;
Daniel Veillardbe803962000-06-28 23:40:59 +0000177static char *encoding = NULL;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000178#ifdef LIBXML_XINCLUDE_ENABLED
179static int xinclude = 0;
180#endif
Daniel Veillard48da9102001-08-07 01:10:10 +0000181static int dtdattrs = 0;
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000182static int loaddtd = 0;
William M. Brack8304d872004-06-08 13:29:32 +0000183static xmllintReturnCode progresult = XMLLINT_RETURN_OK;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000184static int timing = 0;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000185static int generate = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000186static int dropdtd = 0;
Daniel Veillarde2940dd2001-08-22 00:06:49 +0000187#ifdef LIBXML_CATALOG_ENABLED
188static int catalogs = 0;
189static int nocatalogs = 0;
190#endif
Daniel Veillard25048d82004-08-14 22:37:54 +0000191#ifdef LIBXML_C14N_ENABLED
192static int canonical = 0;
Aleksey Sanin83868242009-07-09 10:26:22 +0200193static int canonical_11 = 0;
Aleksey Sanin2650df12005-06-06 17:16:50 +0000194static int exc_canonical = 0;
Daniel Veillard25048d82004-08-14 22:37:54 +0000195#endif
Daniel Veillard81273902003-09-30 00:43:48 +0000196#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +0000197static int stream = 0;
Daniel Veillard7899c5c2003-11-03 12:31:38 +0000198static int walker = 0;
Daniel Veillard81273902003-09-30 00:43:48 +0000199#endif /* LIBXML_READER_ENABLED */
Daniel Veillard8a1b1852003-01-05 22:37:17 +0000200static int chkregister = 0;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +0000201static int nbregister = 0;
Daniel Veillard81273902003-09-30 00:43:48 +0000202#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +0000203static int sax1 = 0;
Daniel Veillard81273902003-09-30 00:43:48 +0000204#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillardb3de70c2003-12-02 22:32:15 +0000205#ifdef LIBXML_PATTERN_ENABLED
206static const char *pattern = NULL;
207static xmlPatternPtr patternc = NULL;
Daniel Veillard2fc6df92005-01-30 18:42:55 +0000208static xmlStreamCtxtPtr patstream = NULL;
Daniel Veillardb3de70c2003-12-02 22:32:15 +0000209#endif
Daniel Veillard1934b0c2009-10-07 10:25:06 +0200210#ifdef LIBXML_XPATH_ENABLED
211static const char *xpathquery = NULL;
212#endif
Daniel Veillard968a03a2012-08-13 12:41:33 +0800213static int options = XML_PARSE_COMPACT | XML_PARSE_BIG_LINES;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000214static int sax = 0;
Daniel Veillard7e5c3f42008-07-29 16:12:31 +0000215static int oldxml10 = 0;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +0000216
Daniel Veillard87076042004-05-03 22:54:49 +0000217/************************************************************************
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000218 * *
219 * Entity loading control and customization. *
220 * *
221 ************************************************************************/
222#define MAX_PATHS 64
Daniel Veillarded121382007-04-17 12:33:19 +0000223#ifdef _WIN32
224# define PATH_SEPARATOR ';'
225#else
226# define PATH_SEPARATOR ':'
227#endif
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000228static xmlChar *paths[MAX_PATHS + 1];
229static int nbpaths = 0;
230static int load_trace = 0;
231
232static
233void parsePath(const xmlChar *path) {
234 const xmlChar *cur;
235
236 if (path == NULL)
237 return;
238 while (*path != 0) {
239 if (nbpaths >= MAX_PATHS) {
240 fprintf(stderr, "MAX_PATHS reached: too many paths\n");
241 return;
242 }
243 cur = path;
Daniel Veillarded121382007-04-17 12:33:19 +0000244 while ((*cur == ' ') || (*cur == PATH_SEPARATOR))
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000245 cur++;
246 path = cur;
Daniel Veillarded121382007-04-17 12:33:19 +0000247 while ((*cur != 0) && (*cur != ' ') && (*cur != PATH_SEPARATOR))
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000248 cur++;
249 if (cur != path) {
250 paths[nbpaths] = xmlStrndup(path, cur - path);
251 if (paths[nbpaths] != NULL)
252 nbpaths++;
253 path = cur;
254 }
255 }
256}
257
Daniel Veillard24505b02005-07-28 23:49:35 +0000258static xmlExternalEntityLoader defaultEntityLoader = NULL;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000259
Daniel Veillardf1edb102009-08-10 14:43:18 +0200260static xmlParserInputPtr
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000261xmllintExternalEntityLoader(const char *URL, const char *ID,
262 xmlParserCtxtPtr ctxt) {
263 xmlParserInputPtr ret;
264 warningSAXFunc warning = NULL;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000265 errorSAXFunc err = NULL;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000266
267 int i;
268 const char *lastsegment = URL;
269 const char *iter = URL;
270
Daniel Veillard5608b172008-01-11 06:53:15 +0000271 if ((nbpaths > 0) && (iter != NULL)) {
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000272 while (*iter != 0) {
273 if (*iter == '/')
274 lastsegment = iter + 1;
275 iter++;
276 }
277 }
278
279 if ((ctxt != NULL) && (ctxt->sax != NULL)) {
280 warning = ctxt->sax->warning;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000281 err = ctxt->sax->error;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000282 ctxt->sax->warning = NULL;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000283 ctxt->sax->error = NULL;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000284 }
285
286 if (defaultEntityLoader != NULL) {
287 ret = defaultEntityLoader(URL, ID, ctxt);
288 if (ret != NULL) {
289 if (warning != NULL)
290 ctxt->sax->warning = warning;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000291 if (err != NULL)
292 ctxt->sax->error = err;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000293 if (load_trace) {
294 fprintf \
295 (stderr,
296 "Loaded URL=\"%s\" ID=\"%s\"\n",
297 URL ? URL : "(null)",
298 ID ? ID : "(null)");
299 }
300 return(ret);
301 }
302 }
303 for (i = 0;i < nbpaths;i++) {
304 xmlChar *newURL;
305
306 newURL = xmlStrdup((const xmlChar *) paths[i]);
307 newURL = xmlStrcat(newURL, (const xmlChar *) "/");
308 newURL = xmlStrcat(newURL, (const xmlChar *) lastsegment);
309 if (newURL != NULL) {
310 ret = defaultEntityLoader((const char *)newURL, ID, ctxt);
311 if (ret != NULL) {
312 if (warning != NULL)
313 ctxt->sax->warning = warning;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000314 if (err != NULL)
315 ctxt->sax->error = err;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000316 if (load_trace) {
317 fprintf \
Daniel Veillardf1edb102009-08-10 14:43:18 +0200318 (stderr,
319 "Loaded URL=\"%s\" ID=\"%s\"\n",
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000320 newURL,
Daniel Veillardf1edb102009-08-10 14:43:18 +0200321 ID ? ID : "(null)");
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000322 }
323 xmlFree(newURL);
324 return(ret);
325 }
326 xmlFree(newURL);
327 }
328 }
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000329 if (err != NULL)
330 ctxt->sax->error = err;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000331 if (warning != NULL) {
332 ctxt->sax->warning = warning;
333 if (URL != NULL)
334 warning(ctxt, "failed to load external entity \"%s\"\n", URL);
335 else if (ID != NULL)
336 warning(ctxt, "failed to load external entity \"%s\"\n", ID);
337 }
338 return(NULL);
339}
340/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +0200341 * *
Daniel Veillard87076042004-05-03 22:54:49 +0000342 * Memory allocation consumption debugging *
Daniel Veillardf1edb102009-08-10 14:43:18 +0200343 * *
Daniel Veillard87076042004-05-03 22:54:49 +0000344 ************************************************************************/
345
Daniel Veillard3af3b592004-05-05 19:22:30 +0000346static void
347OOM(void)
348{
Daniel Veillard87076042004-05-03 22:54:49 +0000349 fprintf(stderr, "Ran out of memory needs > %d bytes\n", maxmem);
William M. Brack8304d872004-06-08 13:29:32 +0000350 progresult = XMLLINT_ERR_MEM;
Daniel Veillard87076042004-05-03 22:54:49 +0000351}
352
Daniel Veillard3af3b592004-05-05 19:22:30 +0000353static void
354myFreeFunc(void *mem)
355{
Daniel Veillard87076042004-05-03 22:54:49 +0000356 xmlMemFree(mem);
357}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000358static void *
359myMallocFunc(size_t size)
360{
Daniel Veillard87076042004-05-03 22:54:49 +0000361 void *ret;
362
363 ret = xmlMemMalloc(size);
364 if (ret != NULL) {
365 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000366 OOM();
367 xmlMemFree(ret);
368 return (NULL);
369 }
Daniel Veillard87076042004-05-03 22:54:49 +0000370 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000371 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000372}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000373static void *
374myReallocFunc(void *mem, size_t size)
375{
Daniel Veillard87076042004-05-03 22:54:49 +0000376 void *ret;
377
378 ret = xmlMemRealloc(mem, size);
379 if (ret != NULL) {
380 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000381 OOM();
382 xmlMemFree(ret);
383 return (NULL);
384 }
Daniel Veillard87076042004-05-03 22:54:49 +0000385 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000386 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000387}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000388static char *
389myStrdupFunc(const char *str)
390{
Daniel Veillard87076042004-05-03 22:54:49 +0000391 char *ret;
392
393 ret = xmlMemoryStrdup(str);
394 if (ret != NULL) {
395 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000396 OOM();
397 xmlFree(ret);
398 return (NULL);
399 }
Daniel Veillard87076042004-05-03 22:54:49 +0000400 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000401 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000402}
Daniel Veillard87076042004-05-03 22:54:49 +0000403/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +0200404 * *
Daniel Veillard87076042004-05-03 22:54:49 +0000405 * Internal timing routines to remove the necessity to have *
406 * unix-specific function calls. *
Daniel Veillardf1edb102009-08-10 14:43:18 +0200407 * *
Daniel Veillard87076042004-05-03 22:54:49 +0000408 ************************************************************************/
Daniel Veillard01db67c2001-12-18 07:09:59 +0000409
Daniel Veillardf1edb102009-08-10 14:43:18 +0200410#ifndef HAVE_GETTIMEOFDAY
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000411#ifdef HAVE_SYS_TIMEB_H
412#ifdef HAVE_SYS_TIME_H
413#ifdef HAVE_FTIME
414
Daniel Veillard01c13b52002-12-10 15:19:08 +0000415static int
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000416my_gettimeofday(struct timeval *tvp, void *tzp)
417{
418 struct timeb timebuffer;
419
420 ftime(&timebuffer);
421 if (tvp) {
422 tvp->tv_sec = timebuffer.time;
423 tvp->tv_usec = timebuffer.millitm * 1000L;
424 }
425 return (0);
426}
427#define HAVE_GETTIMEOFDAY 1
428#define gettimeofday my_gettimeofday
429
430#endif /* HAVE_FTIME */
431#endif /* HAVE_SYS_TIME_H */
432#endif /* HAVE_SYS_TIMEB_H */
433#endif /* !HAVE_GETTIMEOFDAY */
434
Daniel Veillard01db67c2001-12-18 07:09:59 +0000435#if defined(HAVE_GETTIMEOFDAY)
436static struct timeval begin, end;
437
438/*
439 * startTimer: call where you want to start timing
440 */
441static void
442startTimer(void)
443{
444 gettimeofday(&begin, NULL);
445}
446
447/*
448 * endTimer: call where you want to stop timing and to print out a
449 * message about the timing performed; format is a printf
450 * type argument
451 */
David Kilzer4472c3a2016-05-13 15:13:17 +0800452static void XMLCDECL LIBXML_ATTR_FORMAT(1,2)
Daniel Veillard118aed72002-09-24 14:13:13 +0000453endTimer(const char *fmt, ...)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000454{
455 long msec;
456 va_list ap;
457
458 gettimeofday(&end, NULL);
459 msec = end.tv_sec - begin.tv_sec;
460 msec *= 1000;
461 msec += (end.tv_usec - begin.tv_usec) / 1000;
462
463#ifndef HAVE_STDARG_H
464#error "endTimer required stdarg functions"
465#endif
Daniel Veillard118aed72002-09-24 14:13:13 +0000466 va_start(ap, fmt);
467 vfprintf(stderr, fmt, ap);
Daniel Veillard01db67c2001-12-18 07:09:59 +0000468 va_end(ap);
469
470 fprintf(stderr, " took %ld ms\n", msec);
471}
472#elif defined(HAVE_TIME_H)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000473/*
474 * No gettimeofday function, so we have to make do with calling clock.
475 * This is obviously less accurate, but there's little we can do about
476 * that.
477 */
Daniel Veillard90bc3712002-03-07 15:12:58 +0000478#ifndef CLOCKS_PER_SEC
479#define CLOCKS_PER_SEC 100
480#endif
Daniel Veillard01db67c2001-12-18 07:09:59 +0000481
482static clock_t begin, end;
483static void
484startTimer(void)
485{
486 begin = clock();
487}
David Kilzer4472c3a2016-05-13 15:13:17 +0800488static void XMLCDECL LIBXML_ATTR_FORMAT(1,2)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000489endTimer(const char *fmt, ...)
490{
491 long msec;
492 va_list ap;
493
494 end = clock();
495 msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
496
497#ifndef HAVE_STDARG_H
498#error "endTimer required stdarg functions"
499#endif
500 va_start(ap, fmt);
501 vfprintf(stderr, fmt, ap);
502 va_end(ap);
503 fprintf(stderr, " took %ld ms\n", msec);
504}
505#else
506
507/*
508 * We don't have a gettimeofday or time.h, so we just don't do timing
509 */
510static void
511startTimer(void)
512{
513 /*
514 * Do nothing
515 */
516}
David Kilzer4472c3a2016-05-13 15:13:17 +0800517static void XMLCDECL LIBXML_ATTR_FORMAT(1,2)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000518endTimer(char *format, ...)
519{
520 /*
521 * We cannot do anything because we don't have a timing function
522 */
523#ifdef HAVE_STDARG_H
Patrick R. Gansterer023206f2012-05-10 22:17:51 +0800524 va_list ap;
Daniel Veillard01db67c2001-12-18 07:09:59 +0000525 va_start(ap, format);
526 vfprintf(stderr, format, ap);
527 va_end(ap);
Patrick R. Gansterer023206f2012-05-10 22:17:51 +0800528 fprintf(stderr, " was not timed\n");
Daniel Veillard01db67c2001-12-18 07:09:59 +0000529#else
530 /* We don't have gettimeofday, time or stdarg.h, what crazy world is
531 * this ?!
532 */
533#endif
534}
535#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000536/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +0200537 * *
538 * HTML ouput *
539 * *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000540 ************************************************************************/
Daniel Veillard24505b02005-07-28 23:49:35 +0000541static char buffer[50000];
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000542
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000543static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000544xmlHTMLEncodeSend(void) {
545 char *result;
546
547 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
548 if (result) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000549 xmlGenericError(xmlGenericErrorContext, "%s", result);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000550 xmlFree(result);
551 }
552 buffer[0] = 0;
553}
554
555/**
556 * xmlHTMLPrintFileInfo:
557 * @input: an xmlParserInputPtr input
Daniel Veillardf1edb102009-08-10 14:43:18 +0200558 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000559 * Displays the associated file and line informations for the current input
560 */
561
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000562static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000563xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000564 int len;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000565 xmlGenericError(xmlGenericErrorContext, "<p>");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000566
567 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000568 if (input != NULL) {
569 if (input->filename) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000570 snprintf(&buffer[len], sizeof(buffer) - len, "%s:%d: ", input->filename,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000571 input->line);
572 } else {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000573 snprintf(&buffer[len], sizeof(buffer) - len, "Entity: line %d: ", input->line);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000574 }
575 }
576 xmlHTMLEncodeSend();
577}
578
579/**
580 * xmlHTMLPrintFileContext:
581 * @input: an xmlParserInputPtr input
Daniel Veillardf1edb102009-08-10 14:43:18 +0200582 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000583 * Displays current context within the input content for error tracking
584 */
585
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000586static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000587xmlHTMLPrintFileContext(xmlParserInputPtr input) {
588 const xmlChar *cur, *base;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000589 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000590 int n;
591
592 if (input == NULL) return;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000593 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000594 cur = input->cur;
595 base = input->base;
596 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
597 cur--;
598 }
599 n = 0;
600 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
601 cur--;
602 if ((*cur == '\n') || (*cur == '\r')) cur++;
603 base = cur;
604 n = 0;
605 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000606 len = strlen(buffer);
Daniel Veillardf1edb102009-08-10 14:43:18 +0200607 snprintf(&buffer[len], sizeof(buffer) - len, "%c",
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000608 (unsigned char) *cur++);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000609 n++;
610 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000611 len = strlen(buffer);
612 snprintf(&buffer[len], sizeof(buffer) - len, "\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000613 cur = input->cur;
614 while ((*cur == '\n') || (*cur == '\r'))
615 cur--;
616 n = 0;
617 while ((cur != base) && (n++ < 80)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000618 len = strlen(buffer);
619 snprintf(&buffer[len], sizeof(buffer) - len, " ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000620 base++;
621 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000622 len = strlen(buffer);
623 snprintf(&buffer[len], sizeof(buffer) - len, "^\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000624 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000625 xmlGenericError(xmlGenericErrorContext, "</pre>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000626}
627
628/**
629 * xmlHTMLError:
630 * @ctx: an XML parser context
631 * @msg: the message to display/transmit
632 * @...: extra parameters for the message display
Daniel Veillardf1edb102009-08-10 14:43:18 +0200633 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000634 * Display and format an error messages, gives file, line, position and
635 * extra parameters.
636 */
David Kilzer4472c3a2016-05-13 15:13:17 +0800637static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000638xmlHTMLError(void *ctx, const char *msg, ...)
639{
640 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
641 xmlParserInputPtr input;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000642 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000643 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000644
645 buffer[0] = 0;
646 input = ctxt->input;
647 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000648 input = ctxt->inputTab[ctxt->inputNr - 2];
649 }
Daniel Veillardf1edb102009-08-10 14:43:18 +0200650
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000651 xmlHTMLPrintFileInfo(input);
652
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000653 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000654 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000655 len = strlen(buffer);
656 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000657 va_end(args);
658 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000659 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000660
661 xmlHTMLPrintFileContext(input);
662 xmlHTMLEncodeSend();
663}
664
665/**
666 * xmlHTMLWarning:
667 * @ctx: an XML parser context
668 * @msg: the message to display/transmit
669 * @...: extra parameters for the message display
Daniel Veillardf1edb102009-08-10 14:43:18 +0200670 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000671 * Display and format a warning messages, gives file, line, position and
672 * extra parameters.
673 */
David Kilzer4472c3a2016-05-13 15:13:17 +0800674static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000675xmlHTMLWarning(void *ctx, const char *msg, ...)
676{
677 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
678 xmlParserInputPtr input;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000679 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000680 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000681
682 buffer[0] = 0;
683 input = ctxt->input;
684 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000685 input = ctxt->inputTab[ctxt->inputNr - 2];
686 }
Daniel Veillardf1edb102009-08-10 14:43:18 +0200687
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000688
689 xmlHTMLPrintFileInfo(input);
Daniel Veillardf1edb102009-08-10 14:43:18 +0200690
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000691 xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000692 va_start(args, msg);
Daniel Veillardf1edb102009-08-10 14:43:18 +0200693 len = strlen(buffer);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000694 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000695 va_end(args);
696 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000697 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000698
699 xmlHTMLPrintFileContext(input);
700 xmlHTMLEncodeSend();
701}
702
703/**
704 * xmlHTMLValidityError:
705 * @ctx: an XML parser context
706 * @msg: the message to display/transmit
707 * @...: extra parameters for the message display
Daniel Veillardf1edb102009-08-10 14:43:18 +0200708 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000709 * Display and format an validity error messages, gives file,
710 * line, position and extra parameters.
711 */
David Kilzer4472c3a2016-05-13 15:13:17 +0800712static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000713xmlHTMLValidityError(void *ctx, const char *msg, ...)
714{
715 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
716 xmlParserInputPtr input;
717 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000718 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000719
720 buffer[0] = 0;
721 input = ctxt->input;
722 if ((input->filename == NULL) && (ctxt->inputNr > 1))
723 input = ctxt->inputTab[ctxt->inputNr - 2];
Daniel Veillardf1edb102009-08-10 14:43:18 +0200724
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000725 xmlHTMLPrintFileInfo(input);
726
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000727 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000728 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000729 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000730 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000731 va_end(args);
732 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000733 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000734
735 xmlHTMLPrintFileContext(input);
736 xmlHTMLEncodeSend();
Daniel Veillard9fcb4912005-03-16 12:57:31 +0000737 progresult = XMLLINT_ERR_VALID;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000738}
739
740/**
741 * xmlHTMLValidityWarning:
742 * @ctx: an XML parser context
743 * @msg: the message to display/transmit
744 * @...: extra parameters for the message display
Daniel Veillardf1edb102009-08-10 14:43:18 +0200745 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000746 * Display and format a validity warning messages, gives file, line,
747 * position and extra parameters.
748 */
David Kilzer4472c3a2016-05-13 15:13:17 +0800749static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000750xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
751{
752 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
753 xmlParserInputPtr input;
754 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000755 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000756
757 buffer[0] = 0;
758 input = ctxt->input;
759 if ((input->filename == NULL) && (ctxt->inputNr > 1))
760 input = ctxt->inputTab[ctxt->inputNr - 2];
761
762 xmlHTMLPrintFileInfo(input);
Daniel Veillardf1edb102009-08-10 14:43:18 +0200763
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000764 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000765 va_start(args, msg);
Daniel Veillardf1edb102009-08-10 14:43:18 +0200766 len = strlen(buffer);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000767 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000768 va_end(args);
769 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000770 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000771
772 xmlHTMLPrintFileContext(input);
773 xmlHTMLEncodeSend();
774}
775
776/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +0200777 * *
778 * Shell Interface *
779 * *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000780 ************************************************************************/
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000781#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000782#ifdef LIBXML_XPATH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000783/**
784 * xmlShellReadline:
785 * @prompt: the prompt value
786 *
787 * Read a string
Daniel Veillardf1edb102009-08-10 14:43:18 +0200788 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000789 * Returns a pointer to it or NULL on EOF the caller is expected to
790 * free the returned string.
791 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000792static char *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000793xmlShellReadline(char *prompt) {
794#ifdef HAVE_LIBREADLINE
795 char *line_read;
796
797 /* Get a line from the user. */
798 line_read = readline (prompt);
799
800 /* If the line has any text in it, save it on the history. */
801 if (line_read && *line_read)
802 add_history (line_read);
803
804 return (line_read);
805#else
806 char line_read[501];
Daniel Veillard29e43992001-12-13 22:21:58 +0000807 char *ret;
808 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000809
810 if (prompt != NULL)
811 fprintf(stdout, "%s", prompt);
Patrick Monnerat11e805d2015-04-17 17:02:59 +0200812 fflush(stdout);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000813 if (!fgets(line_read, 500, stdin))
814 return(NULL);
815 line_read[500] = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000816 len = strlen(line_read);
817 ret = (char *) malloc(len + 1);
818 if (ret != NULL) {
819 memcpy (ret, line_read, len + 1);
820 }
821 return(ret);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000822#endif
823}
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000824#endif /* LIBXML_XPATH_ENABLED */
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000825#endif /* LIBXML_DEBUG_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000826
827/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +0200828 * *
829 * I/O Interfaces *
830 * *
Daniel Veillard5e873c42000-04-12 13:27:38 +0000831 ************************************************************************/
832
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000833static int myRead(FILE *f, char * buf, int len) {
834 return(fread(buf, 1, len, f));
Daniel Veillard5e873c42000-04-12 13:27:38 +0000835}
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000836static void myClose(FILE *f) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000837 if (f != stdin) {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000838 fclose(f);
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000839 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000840}
841
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000842/************************************************************************
843 * *
Daniel Veillardf1edb102009-08-10 14:43:18 +0200844 * SAX based tests *
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000845 * *
846 ************************************************************************/
847
848/*
849 * empty SAX block
850 */
Daniel Veillard24505b02005-07-28 23:49:35 +0000851static xmlSAXHandler emptySAXHandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000852 NULL, /* internalSubset */
853 NULL, /* isStandalone */
854 NULL, /* hasInternalSubset */
855 NULL, /* hasExternalSubset */
856 NULL, /* resolveEntity */
857 NULL, /* getEntity */
858 NULL, /* entityDecl */
859 NULL, /* notationDecl */
860 NULL, /* attributeDecl */
861 NULL, /* elementDecl */
862 NULL, /* unparsedEntityDecl */
863 NULL, /* setDocumentLocator */
864 NULL, /* startDocument */
865 NULL, /* endDocument */
866 NULL, /* startElement */
867 NULL, /* endElement */
868 NULL, /* reference */
869 NULL, /* characters */
870 NULL, /* ignorableWhitespace */
871 NULL, /* processingInstruction */
872 NULL, /* comment */
873 NULL, /* xmlParserWarning */
874 NULL, /* xmlParserError */
875 NULL, /* xmlParserError */
876 NULL, /* getParameterEntity */
877 NULL, /* cdataBlock; */
878 NULL, /* externalSubset; */
Daniel Veillard971771e2005-07-09 17:32:57 +0000879 XML_SAX2_MAGIC,
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000880 NULL,
881 NULL, /* startElementNs */
882 NULL, /* endElementNs */
883 NULL /* xmlStructuredErrorFunc */
884};
885
Daniel Veillard24505b02005-07-28 23:49:35 +0000886static xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000887extern xmlSAXHandlerPtr debugSAXHandler;
888static int callbacks;
889
890/**
891 * isStandaloneDebug:
892 * @ctxt: An XML parser context
893 *
894 * Is this document tagged standalone ?
895 *
896 * Returns 1 if true
897 */
898static int
899isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
900{
901 callbacks++;
902 if (noout)
903 return(0);
904 fprintf(stdout, "SAX.isStandalone()\n");
905 return(0);
906}
907
908/**
909 * hasInternalSubsetDebug:
910 * @ctxt: An XML parser context
911 *
912 * Does this document has an internal subset
913 *
914 * Returns 1 if true
915 */
916static int
917hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
918{
919 callbacks++;
920 if (noout)
921 return(0);
922 fprintf(stdout, "SAX.hasInternalSubset()\n");
923 return(0);
924}
925
926/**
927 * hasExternalSubsetDebug:
928 * @ctxt: An XML parser context
929 *
930 * Does this document has an external subset
931 *
932 * Returns 1 if true
933 */
934static int
935hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
936{
937 callbacks++;
938 if (noout)
939 return(0);
940 fprintf(stdout, "SAX.hasExternalSubset()\n");
941 return(0);
942}
943
944/**
945 * internalSubsetDebug:
946 * @ctxt: An XML parser context
947 *
948 * Does this document has an internal subset
949 */
950static void
951internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
952 const xmlChar *ExternalID, const xmlChar *SystemID)
953{
954 callbacks++;
955 if (noout)
956 return;
957 fprintf(stdout, "SAX.internalSubset(%s,", name);
958 if (ExternalID == NULL)
959 fprintf(stdout, " ,");
960 else
961 fprintf(stdout, " %s,", ExternalID);
962 if (SystemID == NULL)
963 fprintf(stdout, " )\n");
964 else
965 fprintf(stdout, " %s)\n", SystemID);
966}
967
968/**
969 * externalSubsetDebug:
970 * @ctxt: An XML parser context
971 *
972 * Does this document has an external subset
973 */
974static void
975externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
976 const xmlChar *ExternalID, const xmlChar *SystemID)
977{
978 callbacks++;
979 if (noout)
980 return;
981 fprintf(stdout, "SAX.externalSubset(%s,", name);
982 if (ExternalID == NULL)
983 fprintf(stdout, " ,");
984 else
985 fprintf(stdout, " %s,", ExternalID);
986 if (SystemID == NULL)
987 fprintf(stdout, " )\n");
988 else
989 fprintf(stdout, " %s)\n", SystemID);
990}
991
992/**
993 * resolveEntityDebug:
994 * @ctxt: An XML parser context
995 * @publicId: The public ID of the entity
996 * @systemId: The system ID of the entity
997 *
998 * Special entity resolver, better left to the parser, it has
999 * more context than the application layer.
1000 * The default behaviour is to NOT resolve the entities, in that case
1001 * the ENTITY_REF nodes are built in the structure (and the parameter
1002 * values).
1003 *
1004 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
1005 */
1006static xmlParserInputPtr
1007resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
1008{
1009 callbacks++;
1010 if (noout)
1011 return(NULL);
1012 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1013
Daniel Veillardf1edb102009-08-10 14:43:18 +02001014
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001015 fprintf(stdout, "SAX.resolveEntity(");
1016 if (publicId != NULL)
1017 fprintf(stdout, "%s", (char *)publicId);
1018 else
1019 fprintf(stdout, " ");
1020 if (systemId != NULL)
1021 fprintf(stdout, ", %s)\n", (char *)systemId);
1022 else
1023 fprintf(stdout, ", )\n");
1024 return(NULL);
1025}
1026
1027/**
1028 * getEntityDebug:
1029 * @ctxt: An XML parser context
1030 * @name: The entity name
1031 *
1032 * Get an entity by name
1033 *
1034 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
1035 */
1036static xmlEntityPtr
1037getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1038{
1039 callbacks++;
1040 if (noout)
1041 return(NULL);
1042 fprintf(stdout, "SAX.getEntity(%s)\n", name);
1043 return(NULL);
1044}
1045
1046/**
1047 * getParameterEntityDebug:
1048 * @ctxt: An XML parser context
1049 * @name: The entity name
1050 *
1051 * Get a parameter entity by name
1052 *
1053 * Returns the xmlParserInputPtr
1054 */
1055static xmlEntityPtr
1056getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1057{
1058 callbacks++;
1059 if (noout)
1060 return(NULL);
1061 fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
1062 return(NULL);
1063}
1064
1065
1066/**
1067 * entityDeclDebug:
1068 * @ctxt: An XML parser context
Daniel Veillardf1edb102009-08-10 14:43:18 +02001069 * @name: the entity name
1070 * @type: the entity type
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001071 * @publicId: The public ID of the entity
1072 * @systemId: The system ID of the entity
1073 * @content: the entity value (without processing).
1074 *
1075 * An entity definition has been parsed
1076 */
1077static void
1078entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
1079 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
1080{
1081const xmlChar *nullstr = BAD_CAST "(null)";
1082 /* not all libraries handle printing null pointers nicely */
1083 if (publicId == NULL)
1084 publicId = nullstr;
1085 if (systemId == NULL)
1086 systemId = nullstr;
1087 if (content == NULL)
1088 content = (xmlChar *)nullstr;
1089 callbacks++;
1090 if (noout)
1091 return;
1092 fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
1093 name, type, publicId, systemId, content);
1094}
1095
1096/**
1097 * attributeDeclDebug:
1098 * @ctxt: An XML parser context
Daniel Veillardf1edb102009-08-10 14:43:18 +02001099 * @name: the attribute name
1100 * @type: the attribute type
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001101 *
1102 * An attribute definition has been parsed
1103 */
1104static void
1105attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar * elem,
1106 const xmlChar * name, int type, int def,
1107 const xmlChar * defaultValue, xmlEnumerationPtr tree)
1108{
1109 callbacks++;
1110 if (noout)
1111 return;
1112 if (defaultValue == NULL)
1113 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
1114 elem, name, type, def);
1115 else
1116 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
1117 elem, name, type, def, defaultValue);
1118 xmlFreeEnumeration(tree);
1119}
1120
1121/**
1122 * elementDeclDebug:
1123 * @ctxt: An XML parser context
Daniel Veillardf1edb102009-08-10 14:43:18 +02001124 * @name: the element name
1125 * @type: the element type
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001126 * @content: the element value (without processing).
1127 *
1128 * An element definition has been parsed
1129 */
1130static void
1131elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
1132 xmlElementContentPtr content ATTRIBUTE_UNUSED)
1133{
1134 callbacks++;
1135 if (noout)
1136 return;
1137 fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
1138 name, type);
1139}
1140
1141/**
1142 * notationDeclDebug:
1143 * @ctxt: An XML parser context
1144 * @name: The name of the notation
1145 * @publicId: The public ID of the entity
1146 * @systemId: The system ID of the entity
1147 *
1148 * What to do when a notation declaration has been parsed.
1149 */
1150static void
1151notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
1152 const xmlChar *publicId, const xmlChar *systemId)
1153{
1154 callbacks++;
1155 if (noout)
1156 return;
1157 fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
1158 (char *) name, (char *) publicId, (char *) systemId);
1159}
1160
1161/**
1162 * unparsedEntityDeclDebug:
1163 * @ctxt: An XML parser context
1164 * @name: The name of the entity
1165 * @publicId: The public ID of the entity
1166 * @systemId: The system ID of the entity
1167 * @notationName: the name of the notation
1168 *
1169 * What to do when an unparsed entity declaration is parsed
1170 */
1171static void
1172unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
1173 const xmlChar *publicId, const xmlChar *systemId,
1174 const xmlChar *notationName)
1175{
1176const xmlChar *nullstr = BAD_CAST "(null)";
1177
1178 if (publicId == NULL)
1179 publicId = nullstr;
1180 if (systemId == NULL)
1181 systemId = nullstr;
1182 if (notationName == NULL)
1183 notationName = nullstr;
1184 callbacks++;
1185 if (noout)
1186 return;
1187 fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
1188 (char *) name, (char *) publicId, (char *) systemId,
1189 (char *) notationName);
1190}
1191
1192/**
1193 * setDocumentLocatorDebug:
1194 * @ctxt: An XML parser context
1195 * @loc: A SAX Locator
1196 *
1197 * Receive the document locator at startup, actually xmlDefaultSAXLocator
1198 * Everything is available on the context, so this is useless in our case.
1199 */
1200static void
1201setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
1202{
1203 callbacks++;
1204 if (noout)
1205 return;
1206 fprintf(stdout, "SAX.setDocumentLocator()\n");
1207}
1208
1209/**
1210 * startDocumentDebug:
1211 * @ctxt: An XML parser context
1212 *
1213 * called when the document start being processed.
1214 */
1215static void
1216startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
1217{
1218 callbacks++;
1219 if (noout)
1220 return;
1221 fprintf(stdout, "SAX.startDocument()\n");
1222}
1223
1224/**
1225 * endDocumentDebug:
1226 * @ctxt: An XML parser context
1227 *
1228 * called when the document end has been detected.
1229 */
1230static void
1231endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
1232{
1233 callbacks++;
1234 if (noout)
1235 return;
1236 fprintf(stdout, "SAX.endDocument()\n");
1237}
1238
1239/**
1240 * startElementDebug:
1241 * @ctxt: An XML parser context
1242 * @name: The element name
1243 *
1244 * called when an opening tag has been processed.
1245 */
1246static void
1247startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
1248{
1249 int i;
1250
1251 callbacks++;
1252 if (noout)
1253 return;
1254 fprintf(stdout, "SAX.startElement(%s", (char *) name);
1255 if (atts != NULL) {
1256 for (i = 0;(atts[i] != NULL);i++) {
1257 fprintf(stdout, ", %s='", atts[i++]);
1258 if (atts[i] != NULL)
1259 fprintf(stdout, "%s'", atts[i]);
1260 }
1261 }
1262 fprintf(stdout, ")\n");
1263}
1264
1265/**
1266 * endElementDebug:
1267 * @ctxt: An XML parser context
1268 * @name: The element name
1269 *
1270 * called when the end of an element has been detected.
1271 */
1272static void
1273endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1274{
1275 callbacks++;
1276 if (noout)
1277 return;
1278 fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
1279}
1280
1281/**
1282 * charactersDebug:
1283 * @ctxt: An XML parser context
1284 * @ch: a xmlChar string
1285 * @len: the number of xmlChar
1286 *
1287 * receiving some chars from the parser.
1288 * Question: how much at a time ???
1289 */
1290static void
1291charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
1292{
1293 char out[40];
1294 int i;
1295
1296 callbacks++;
1297 if (noout)
1298 return;
1299 for (i = 0;(i<len) && (i < 30);i++)
1300 out[i] = ch[i];
1301 out[i] = 0;
1302
1303 fprintf(stdout, "SAX.characters(%s, %d)\n", out, len);
1304}
1305
1306/**
1307 * referenceDebug:
1308 * @ctxt: An XML parser context
1309 * @name: The entity name
1310 *
Daniel Veillardf1edb102009-08-10 14:43:18 +02001311 * called when an entity reference is detected.
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001312 */
1313static void
1314referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1315{
1316 callbacks++;
1317 if (noout)
1318 return;
1319 fprintf(stdout, "SAX.reference(%s)\n", name);
1320}
1321
1322/**
1323 * ignorableWhitespaceDebug:
1324 * @ctxt: An XML parser context
1325 * @ch: a xmlChar string
1326 * @start: the first char in the string
1327 * @len: the number of xmlChar
1328 *
1329 * receiving some ignorable whitespaces from the parser.
1330 * Question: how much at a time ???
1331 */
1332static void
1333ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
1334{
1335 char out[40];
1336 int i;
1337
1338 callbacks++;
1339 if (noout)
1340 return;
1341 for (i = 0;(i<len) && (i < 30);i++)
1342 out[i] = ch[i];
1343 out[i] = 0;
1344 fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", out, len);
1345}
1346
1347/**
1348 * processingInstructionDebug:
1349 * @ctxt: An XML parser context
1350 * @target: the target name
1351 * @data: the PI data's
1352 * @len: the number of xmlChar
1353 *
1354 * A processing instruction has been parsed.
1355 */
1356static void
1357processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
1358 const xmlChar *data)
1359{
1360 callbacks++;
1361 if (noout)
1362 return;
1363 if (data != NULL)
1364 fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
1365 (char *) target, (char *) data);
1366 else
1367 fprintf(stdout, "SAX.processingInstruction(%s, NULL)\n",
1368 (char *) target);
1369}
1370
1371/**
1372 * cdataBlockDebug:
1373 * @ctx: the user data (XML parser context)
1374 * @value: The pcdata content
1375 * @len: the block length
1376 *
1377 * called when a pcdata block has been parsed
1378 */
1379static void
1380cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
1381{
1382 callbacks++;
1383 if (noout)
1384 return;
1385 fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
1386 (char *) value, len);
1387}
1388
1389/**
1390 * commentDebug:
1391 * @ctxt: An XML parser context
1392 * @value: the comment content
1393 *
1394 * A comment has been parsed.
1395 */
1396static void
1397commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
1398{
1399 callbacks++;
1400 if (noout)
1401 return;
1402 fprintf(stdout, "SAX.comment(%s)\n", value);
1403}
1404
1405/**
1406 * warningDebug:
1407 * @ctxt: An XML parser context
1408 * @msg: the message to display/transmit
1409 * @...: extra parameters for the message display
1410 *
1411 * Display and format a warning messages, gives file, line, position and
1412 * extra parameters.
1413 */
David Kilzer4472c3a2016-05-13 15:13:17 +08001414static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001415warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1416{
1417 va_list args;
1418
1419 callbacks++;
1420 if (noout)
1421 return;
1422 va_start(args, msg);
1423 fprintf(stdout, "SAX.warning: ");
1424 vfprintf(stdout, msg, args);
1425 va_end(args);
1426}
1427
1428/**
1429 * errorDebug:
1430 * @ctxt: An XML parser context
1431 * @msg: the message to display/transmit
1432 * @...: extra parameters for the message display
1433 *
1434 * Display and format a error messages, gives file, line, position and
1435 * extra parameters.
1436 */
David Kilzer4472c3a2016-05-13 15:13:17 +08001437static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001438errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1439{
1440 va_list args;
1441
1442 callbacks++;
1443 if (noout)
1444 return;
1445 va_start(args, msg);
1446 fprintf(stdout, "SAX.error: ");
1447 vfprintf(stdout, msg, args);
1448 va_end(args);
1449}
1450
1451/**
1452 * fatalErrorDebug:
1453 * @ctxt: An XML parser context
1454 * @msg: the message to display/transmit
1455 * @...: extra parameters for the message display
1456 *
1457 * Display and format a fatalError messages, gives file, line, position and
1458 * extra parameters.
1459 */
David Kilzer4472c3a2016-05-13 15:13:17 +08001460static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001461fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1462{
1463 va_list args;
1464
1465 callbacks++;
1466 if (noout)
1467 return;
1468 va_start(args, msg);
1469 fprintf(stdout, "SAX.fatalError: ");
1470 vfprintf(stdout, msg, args);
1471 va_end(args);
1472}
1473
Daniel Veillard24505b02005-07-28 23:49:35 +00001474static xmlSAXHandler debugSAXHandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001475 internalSubsetDebug,
1476 isStandaloneDebug,
1477 hasInternalSubsetDebug,
1478 hasExternalSubsetDebug,
1479 resolveEntityDebug,
1480 getEntityDebug,
1481 entityDeclDebug,
1482 notationDeclDebug,
1483 attributeDeclDebug,
1484 elementDeclDebug,
1485 unparsedEntityDeclDebug,
1486 setDocumentLocatorDebug,
1487 startDocumentDebug,
1488 endDocumentDebug,
1489 startElementDebug,
1490 endElementDebug,
1491 referenceDebug,
1492 charactersDebug,
1493 ignorableWhitespaceDebug,
1494 processingInstructionDebug,
1495 commentDebug,
1496 warningDebug,
1497 errorDebug,
1498 fatalErrorDebug,
1499 getParameterEntityDebug,
1500 cdataBlockDebug,
1501 externalSubsetDebug,
1502 1,
1503 NULL,
1504 NULL,
1505 NULL,
1506 NULL
1507};
1508
1509xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
1510
1511/*
1512 * SAX2 specific callbacks
1513 */
1514/**
1515 * startElementNsDebug:
1516 * @ctxt: An XML parser context
1517 * @name: The element name
1518 *
1519 * called when an opening tag has been processed.
1520 */
1521static void
1522startElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
1523 const xmlChar *localname,
1524 const xmlChar *prefix,
1525 const xmlChar *URI,
1526 int nb_namespaces,
1527 const xmlChar **namespaces,
1528 int nb_attributes,
1529 int nb_defaulted,
1530 const xmlChar **attributes)
1531{
1532 int i;
1533
1534 callbacks++;
1535 if (noout)
1536 return;
1537 fprintf(stdout, "SAX.startElementNs(%s", (char *) localname);
1538 if (prefix == NULL)
1539 fprintf(stdout, ", NULL");
1540 else
1541 fprintf(stdout, ", %s", (char *) prefix);
1542 if (URI == NULL)
1543 fprintf(stdout, ", NULL");
1544 else
1545 fprintf(stdout, ", '%s'", (char *) URI);
1546 fprintf(stdout, ", %d", nb_namespaces);
Daniel Veillardf1edb102009-08-10 14:43:18 +02001547
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001548 if (namespaces != NULL) {
1549 for (i = 0;i < nb_namespaces * 2;i++) {
1550 fprintf(stdout, ", xmlns");
1551 if (namespaces[i] != NULL)
1552 fprintf(stdout, ":%s", namespaces[i]);
1553 i++;
1554 fprintf(stdout, "='%s'", namespaces[i]);
1555 }
1556 }
1557 fprintf(stdout, ", %d, %d", nb_attributes, nb_defaulted);
1558 if (attributes != NULL) {
1559 for (i = 0;i < nb_attributes * 5;i += 5) {
1560 if (attributes[i + 1] != NULL)
1561 fprintf(stdout, ", %s:%s='", attributes[i + 1], attributes[i]);
1562 else
1563 fprintf(stdout, ", %s='", attributes[i]);
1564 fprintf(stdout, "%.4s...', %d", attributes[i + 3],
1565 (int)(attributes[i + 4] - attributes[i + 3]));
1566 }
1567 }
1568 fprintf(stdout, ")\n");
1569}
1570
1571/**
1572 * endElementDebug:
1573 * @ctxt: An XML parser context
1574 * @name: The element name
1575 *
1576 * called when the end of an element has been detected.
1577 */
1578static void
1579endElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
1580 const xmlChar *localname,
1581 const xmlChar *prefix,
1582 const xmlChar *URI)
1583{
1584 callbacks++;
1585 if (noout)
1586 return;
1587 fprintf(stdout, "SAX.endElementNs(%s", (char *) localname);
1588 if (prefix == NULL)
1589 fprintf(stdout, ", NULL");
1590 else
1591 fprintf(stdout, ", %s", (char *) prefix);
1592 if (URI == NULL)
1593 fprintf(stdout, ", NULL)\n");
1594 else
1595 fprintf(stdout, ", '%s')\n", (char *) URI);
1596}
1597
Daniel Veillard24505b02005-07-28 23:49:35 +00001598static xmlSAXHandler debugSAX2HandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001599 internalSubsetDebug,
1600 isStandaloneDebug,
1601 hasInternalSubsetDebug,
1602 hasExternalSubsetDebug,
1603 resolveEntityDebug,
1604 getEntityDebug,
1605 entityDeclDebug,
1606 notationDeclDebug,
1607 attributeDeclDebug,
1608 elementDeclDebug,
1609 unparsedEntityDeclDebug,
1610 setDocumentLocatorDebug,
1611 startDocumentDebug,
1612 endDocumentDebug,
1613 NULL,
1614 NULL,
1615 referenceDebug,
1616 charactersDebug,
1617 ignorableWhitespaceDebug,
1618 processingInstructionDebug,
1619 commentDebug,
1620 warningDebug,
1621 errorDebug,
1622 fatalErrorDebug,
1623 getParameterEntityDebug,
1624 cdataBlockDebug,
1625 externalSubsetDebug,
1626 XML_SAX2_MAGIC,
1627 NULL,
1628 startElementNsDebug,
1629 endElementNsDebug,
1630 NULL
1631};
1632
Daniel Veillard24505b02005-07-28 23:49:35 +00001633static xmlSAXHandlerPtr debugSAX2Handler = &debugSAX2HandlerStruct;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001634
1635static void
1636testSAX(const char *filename) {
1637 xmlSAXHandlerPtr handler;
1638 const char *user_data = "user_data"; /* mostly for debugging */
1639 xmlParserInputBufferPtr buf = NULL;
1640 xmlParserInputPtr inputStream;
1641 xmlParserCtxtPtr ctxt = NULL;
1642 xmlSAXHandlerPtr old_sax = NULL;
1643
1644 callbacks = 0;
1645
1646 if (noout) {
1647 handler = emptySAXHandler;
Daniel Veillard78dfc9f2005-07-10 22:30:30 +00001648#ifdef LIBXML_SAX1_ENABLED
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001649 } else if (sax1) {
1650 handler = debugSAXHandler;
Daniel Veillard78dfc9f2005-07-10 22:30:30 +00001651#endif
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001652 } else {
1653 handler = debugSAX2Handler;
1654 }
1655
1656 /*
1657 * it's not the simplest code but the most generic in term of I/O
1658 */
1659 buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
1660 if (buf == NULL) {
1661 goto error;
1662 }
1663
1664#ifdef LIBXML_SCHEMAS_ENABLED
1665 if (wxschemas != NULL) {
1666 int ret;
1667 xmlSchemaValidCtxtPtr vctxt;
1668
1669 vctxt = xmlSchemaNewValidCtxt(wxschemas);
1670 xmlSchemaSetValidErrors(vctxt,
1671 (xmlSchemaValidityErrorFunc) fprintf,
1672 (xmlSchemaValidityWarningFunc) fprintf,
1673 stderr);
Daniel Veillard97fa5b32012-08-14 11:01:07 +08001674 xmlSchemaValidateSetFilename(vctxt, filename);
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001675
Daniel Veillard971771e2005-07-09 17:32:57 +00001676 ret = xmlSchemaValidateStream(vctxt, buf, 0, handler,
1677 (void *)user_data);
1678 if (repeat == 0) {
1679 if (ret == 0) {
1680 fprintf(stderr, "%s validates\n", filename);
1681 } else if (ret > 0) {
1682 fprintf(stderr, "%s fails to validate\n", filename);
1683 progresult = XMLLINT_ERR_VALID;
1684 } else {
1685 fprintf(stderr, "%s validation generated an internal error\n",
1686 filename);
1687 progresult = XMLLINT_ERR_VALID;
1688 }
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001689 }
1690 xmlSchemaFreeValidCtxt(vctxt);
1691 } else
1692#endif
1693 {
1694 /*
1695 * Create the parser context amd hook the input
1696 */
1697 ctxt = xmlNewParserCtxt();
1698 if (ctxt == NULL) {
1699 xmlFreeParserInputBuffer(buf);
1700 goto error;
1701 }
1702 old_sax = ctxt->sax;
1703 ctxt->sax = handler;
1704 ctxt->userData = (void *) user_data;
1705 inputStream = xmlNewIOInputStream(ctxt, buf, XML_CHAR_ENCODING_NONE);
1706 if (inputStream == NULL) {
1707 xmlFreeParserInputBuffer(buf);
1708 goto error;
1709 }
1710 inputPush(ctxt, inputStream);
Daniel Veillardf1edb102009-08-10 14:43:18 +02001711
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001712 /* do the parsing */
1713 xmlParseDocument(ctxt);
1714
1715 if (ctxt->myDoc != NULL) {
1716 fprintf(stderr, "SAX generated a doc !\n");
1717 xmlFreeDoc(ctxt->myDoc);
1718 ctxt->myDoc = NULL;
1719 }
1720 }
1721
1722error:
1723 if (ctxt != NULL) {
1724 ctxt->sax = old_sax;
1725 xmlFreeParserCtxt(ctxt);
1726 }
1727}
1728
Daniel Veillard5e873c42000-04-12 13:27:38 +00001729/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +02001730 * *
1731 * Stream Test processing *
1732 * *
Daniel Veillard7704fb12003-01-03 16:19:51 +00001733 ************************************************************************/
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001734#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00001735static void processNode(xmlTextReaderPtr reader) {
Daniel Veillard198c1bf2003-10-20 17:07:41 +00001736 const xmlChar *name, *value;
Daniel Veillard16ef8002005-01-31 00:27:50 +00001737 int type, empty;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001738
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001739 type = xmlTextReaderNodeType(reader);
Daniel Veillard16ef8002005-01-31 00:27:50 +00001740 empty = xmlTextReaderIsEmptyElement(reader);
Daniel Veillard99737f52003-03-22 14:55:50 +00001741
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001742 if (debug) {
1743 name = xmlTextReaderConstName(reader);
1744 if (name == NULL)
1745 name = BAD_CAST "--";
Daniel Veillard7704fb12003-01-03 16:19:51 +00001746
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001747 value = xmlTextReaderConstValue(reader);
1748
Daniel Veillardf1edb102009-08-10 14:43:18 +02001749
1750 printf("%d %d %s %d %d",
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001751 xmlTextReaderDepth(reader),
1752 type,
1753 name,
Daniel Veillard16ef8002005-01-31 00:27:50 +00001754 empty,
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001755 xmlTextReaderHasValue(reader));
1756 if (value == NULL)
1757 printf("\n");
1758 else {
1759 printf(" %s\n", value);
1760 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001761 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001762#ifdef LIBXML_PATTERN_ENABLED
1763 if (patternc) {
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001764 xmlChar *path = NULL;
1765 int match = -1;
Daniel Veillardf1edb102009-08-10 14:43:18 +02001766
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001767 if (type == XML_READER_TYPE_ELEMENT) {
1768 /* do the check only on element start */
1769 match = xmlPatternMatch(patternc, xmlTextReaderCurrentNode(reader));
1770
1771 if (match) {
Daniel Veillardf1edb102009-08-10 14:43:18 +02001772#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001773 path = xmlGetNodePath(xmlTextReaderCurrentNode(reader));
1774 printf("Node %s matches pattern %s\n", path, pattern);
Daniel Veillardf1edb102009-08-10 14:43:18 +02001775#else
1776 printf("Node %s matches pattern %s\n",
1777 xmlTextReaderConstName(reader), pattern);
1778#endif
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001779 }
1780 }
1781 if (patstream != NULL) {
1782 int ret;
1783
1784 if (type == XML_READER_TYPE_ELEMENT) {
1785 ret = xmlStreamPush(patstream,
1786 xmlTextReaderConstLocalName(reader),
1787 xmlTextReaderConstNamespaceUri(reader));
1788 if (ret < 0) {
1789 fprintf(stderr, "xmlStreamPush() failure\n");
1790 xmlFreeStreamCtxt(patstream);
1791 patstream = NULL;
1792 } else if (ret != match) {
Daniel Veillardf1edb102009-08-10 14:43:18 +02001793#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001794 if (path == NULL) {
1795 path = xmlGetNodePath(
1796 xmlTextReaderCurrentNode(reader));
1797 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02001798#endif
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001799 fprintf(stderr,
1800 "xmlPatternMatch and xmlStreamPush disagree\n");
Daniel Veillardf1edb102009-08-10 14:43:18 +02001801 if (path != NULL)
1802 fprintf(stderr, " pattern %s node %s\n",
1803 pattern, path);
1804 else
1805 fprintf(stderr, " pattern %s node %s\n",
1806 pattern, xmlTextReaderConstName(reader));
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001807 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001808
Daniel Veillardf1edb102009-08-10 14:43:18 +02001809 }
Daniel Veillard16ef8002005-01-31 00:27:50 +00001810 if ((type == XML_READER_TYPE_END_ELEMENT) ||
1811 ((type == XML_READER_TYPE_ELEMENT) && (empty))) {
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001812 ret = xmlStreamPop(patstream);
1813 if (ret < 0) {
1814 fprintf(stderr, "xmlStreamPop() failure\n");
1815 xmlFreeStreamCtxt(patstream);
1816 patstream = NULL;
1817 }
1818 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001819 }
Daniel Veillardf9d16912005-01-30 22:36:30 +00001820 if (path != NULL)
1821 xmlFree(path);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001822 }
1823#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001824}
1825
1826static void streamFile(char *filename) {
1827 xmlTextReaderPtr reader;
1828 int ret;
Daniel Richard G5706b6d2012-08-06 11:32:54 +08001829#ifdef HAVE_MMAP
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001830 int fd = -1;
1831 struct stat info;
1832 const char *base = NULL;
1833 xmlParserInputBufferPtr input = NULL;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001834
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001835 if (memory) {
Daniel Veillardf1edb102009-08-10 14:43:18 +02001836 if (stat(filename, &info) < 0)
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001837 return;
1838 if ((fd = open(filename, O_RDONLY)) < 0)
1839 return;
1840 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillardb98c6a02013-07-12 12:08:40 +08001841 if (base == (void *) MAP_FAILED) {
1842 close(fd);
1843 fprintf(stderr, "mmap failure for file %s\n", filename);
1844 progresult = XMLLINT_ERR_RDFILE;
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001845 return;
Daniel Veillardb98c6a02013-07-12 12:08:40 +08001846 }
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001847
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001848 reader = xmlReaderForMemory(base, info.st_size, filename,
1849 NULL, options);
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001850 } else
1851#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001852 reader = xmlReaderForFile(filename, NULL, options);
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001853#ifdef LIBXML_PATTERN_ENABLED
Daniel Veillardd4301ab2005-02-03 22:24:10 +00001854 if (pattern != NULL) {
1855 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
1856 if (patternc == NULL) {
1857 xmlGenericError(xmlGenericErrorContext,
1858 "Pattern %s failed to compile\n", pattern);
1859 progresult = XMLLINT_ERR_SCHEMAPAT;
1860 pattern = NULL;
1861 }
1862 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001863 if (patternc != NULL) {
1864 patstream = xmlPatternGetStreamCtxt(patternc);
1865 if (patstream != NULL) {
1866 ret = xmlStreamPush(patstream, NULL, NULL);
1867 if (ret < 0) {
1868 fprintf(stderr, "xmlStreamPush() failure\n");
1869 xmlFreeStreamCtxt(patstream);
1870 patstream = NULL;
1871 }
1872 }
1873 }
1874#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001875
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001876
Daniel Veillard7704fb12003-01-03 16:19:51 +00001877 if (reader != NULL) {
Daniel Veillard4432df22003-09-28 18:58:27 +00001878#ifdef LIBXML_VALID_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00001879 if (valid)
1880 xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
Daniel Veillardce192eb2003-04-16 15:58:05 +00001881 else
Daniel Veillard4432df22003-09-28 18:58:27 +00001882#endif /* LIBXML_VALID_ENABLED */
Daniel Veillarde4d16d72012-12-21 10:58:14 +08001883 if (loaddtd)
1884 xmlTextReaderSetParserProp(reader, XML_PARSER_LOADDTD, 1);
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001885#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +00001886 if (relaxng != NULL) {
Daniel Veillard81514ba2003-09-16 23:17:26 +00001887 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001888 startTimer();
1889 }
1890 ret = xmlTextReaderRelaxNGValidate(reader, relaxng);
1891 if (ret < 0) {
1892 xmlGenericError(xmlGenericErrorContext,
1893 "Relax-NG schema %s failed to compile\n", relaxng);
William M. Brack8304d872004-06-08 13:29:32 +00001894 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillardce192eb2003-04-16 15:58:05 +00001895 relaxng = NULL;
1896 }
Daniel Veillard81514ba2003-09-16 23:17:26 +00001897 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001898 endTimer("Compiling the schemas");
1899 }
1900 }
Daniel Veillardf10ae122005-07-10 19:03:16 +00001901 if (schema != NULL) {
1902 if ((timing) && (!repeat)) {
1903 startTimer();
1904 }
1905 ret = xmlTextReaderSchemaValidate(reader, schema);
1906 if (ret < 0) {
1907 xmlGenericError(xmlGenericErrorContext,
1908 "XSD schema %s failed to compile\n", schema);
1909 progresult = XMLLINT_ERR_SCHEMACOMP;
1910 schema = NULL;
1911 }
1912 if ((timing) && (!repeat)) {
1913 endTimer("Compiling the schemas");
1914 }
1915 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001916#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001917
1918 /*
1919 * Process all nodes in sequence
1920 */
Daniel Veillard81514ba2003-09-16 23:17:26 +00001921 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001922 startTimer();
1923 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001924 ret = xmlTextReaderRead(reader);
1925 while (ret == 1) {
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001926 if ((debug)
1927#ifdef LIBXML_PATTERN_ENABLED
1928 || (patternc)
1929#endif
1930 )
Daniel Veillard7704fb12003-01-03 16:19:51 +00001931 processNode(reader);
1932 ret = xmlTextReaderRead(reader);
1933 }
Daniel Veillard81514ba2003-09-16 23:17:26 +00001934 if ((timing) && (!repeat)) {
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001935#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf54cd532004-02-25 11:52:31 +00001936 if (relaxng != NULL)
Daniel Veillard49138f12004-02-19 12:58:36 +00001937 endTimer("Parsing and validating");
1938 else
Daniel Veillardf54cd532004-02-25 11:52:31 +00001939#endif
Daniel Veillard4432df22003-09-28 18:58:27 +00001940#ifdef LIBXML_VALID_ENABLED
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001941 if (valid)
Daniel Veillardce192eb2003-04-16 15:58:05 +00001942 endTimer("Parsing and validating");
1943 else
Daniel Veillard4432df22003-09-28 18:58:27 +00001944#endif
Daniel Veillardf54cd532004-02-25 11:52:31 +00001945 endTimer("Parsing");
Daniel Veillardce192eb2003-04-16 15:58:05 +00001946 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001947
Daniel Veillard4432df22003-09-28 18:58:27 +00001948#ifdef LIBXML_VALID_ENABLED
Daniel Veillardf6bad792003-04-11 19:38:54 +00001949 if (valid) {
1950 if (xmlTextReaderIsValid(reader) != 1) {
1951 xmlGenericError(xmlGenericErrorContext,
1952 "Document %s does not validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001953 progresult = XMLLINT_ERR_VALID;
Daniel Veillardf6bad792003-04-11 19:38:54 +00001954 }
1955 }
Daniel Veillard4432df22003-09-28 18:58:27 +00001956#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001957#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf10ae122005-07-10 19:03:16 +00001958 if ((relaxng != NULL) || (schema != NULL)) {
Daniel Veillardf4e55762003-04-15 23:32:22 +00001959 if (xmlTextReaderIsValid(reader) != 1) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001960 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001961 progresult = XMLLINT_ERR_VALID;
Daniel Veillardf4e55762003-04-15 23:32:22 +00001962 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001963 fprintf(stderr, "%s validates\n", filename);
Daniel Veillardf4e55762003-04-15 23:32:22 +00001964 }
1965 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001966#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001967 /*
1968 * Done, cleanup and status
1969 */
1970 xmlFreeTextReader(reader);
1971 if (ret != 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001972 fprintf(stderr, "%s : failed to parse\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001973 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001974 }
1975 } else {
1976 fprintf(stderr, "Unable to open %s\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001977 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001978 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001979#ifdef LIBXML_PATTERN_ENABLED
1980 if (patstream != NULL) {
1981 xmlFreeStreamCtxt(patstream);
1982 patstream = NULL;
1983 }
1984#endif
Daniel Richard G5706b6d2012-08-06 11:32:54 +08001985#ifdef HAVE_MMAP
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001986 if (memory) {
1987 xmlFreeParserInputBuffer(input);
1988 munmap((char *) base, info.st_size);
1989 close(fd);
1990 }
1991#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001992}
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001993
1994static void walkDoc(xmlDocPtr doc) {
1995 xmlTextReaderPtr reader;
1996 int ret;
1997
Daniel Veillardd4301ab2005-02-03 22:24:10 +00001998#ifdef LIBXML_PATTERN_ENABLED
1999 xmlNodePtr root;
2000 const xmlChar *namespaces[22];
2001 int i;
2002 xmlNsPtr ns;
2003
2004 root = xmlDocGetRootElement(doc);
Hugh Davenportb8e0fa32016-05-04 10:55:49 +08002005 if (root == NULL ) {
2006 xmlGenericError(xmlGenericErrorContext,
2007 "Document does not have a root element");
2008 progresult = XMLLINT_ERR_UNCLASS;
2009 return;
2010 }
Daniel Veillardd4301ab2005-02-03 22:24:10 +00002011 for (ns = root->nsDef, i = 0;ns != NULL && i < 20;ns=ns->next) {
2012 namespaces[i++] = ns->href;
2013 namespaces[i++] = ns->prefix;
2014 }
2015 namespaces[i++] = NULL;
Daniel Veillard13cee4e2009-09-05 14:52:55 +02002016 namespaces[i] = NULL;
Daniel Veillardd4301ab2005-02-03 22:24:10 +00002017
2018 if (pattern != NULL) {
2019 patternc = xmlPatterncompile((const xmlChar *) pattern, doc->dict,
2020 0, &namespaces[0]);
2021 if (patternc == NULL) {
2022 xmlGenericError(xmlGenericErrorContext,
2023 "Pattern %s failed to compile\n", pattern);
2024 progresult = XMLLINT_ERR_SCHEMAPAT;
2025 pattern = NULL;
2026 }
2027 }
Daniel Veillard2b2e02d2005-02-05 23:20:22 +00002028 if (patternc != NULL) {
2029 patstream = xmlPatternGetStreamCtxt(patternc);
2030 if (patstream != NULL) {
2031 ret = xmlStreamPush(patstream, NULL, NULL);
2032 if (ret < 0) {
2033 fprintf(stderr, "xmlStreamPush() failure\n");
2034 xmlFreeStreamCtxt(patstream);
2035 patstream = NULL;
2036 }
2037 }
2038 }
Daniel Veillardd4301ab2005-02-03 22:24:10 +00002039#endif /* LIBXML_PATTERN_ENABLED */
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002040 reader = xmlReaderWalker(doc);
2041 if (reader != NULL) {
2042 if ((timing) && (!repeat)) {
2043 startTimer();
2044 }
2045 ret = xmlTextReaderRead(reader);
2046 while (ret == 1) {
Daniel Veillardb3de70c2003-12-02 22:32:15 +00002047 if ((debug)
2048#ifdef LIBXML_PATTERN_ENABLED
2049 || (patternc)
2050#endif
2051 )
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002052 processNode(reader);
2053 ret = xmlTextReaderRead(reader);
2054 }
2055 if ((timing) && (!repeat)) {
2056 endTimer("walking through the doc");
2057 }
2058 xmlFreeTextReader(reader);
2059 if (ret != 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002060 fprintf(stderr, "failed to walk through the doc\n");
William M. Brack8304d872004-06-08 13:29:32 +00002061 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002062 }
2063 } else {
2064 fprintf(stderr, "Failed to crate a reader from the document\n");
William M. Brack8304d872004-06-08 13:29:32 +00002065 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002066 }
Daniel Veillard2b2e02d2005-02-05 23:20:22 +00002067#ifdef LIBXML_PATTERN_ENABLED
2068 if (patstream != NULL) {
2069 xmlFreeStreamCtxt(patstream);
2070 patstream = NULL;
2071 }
2072#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002073}
Daniel Veillard81273902003-09-30 00:43:48 +00002074#endif /* LIBXML_READER_ENABLED */
Daniel Veillard7704fb12003-01-03 16:19:51 +00002075
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002076#ifdef LIBXML_XPATH_ENABLED
2077/************************************************************************
2078 * *
2079 * XPath Query *
2080 * *
2081 ************************************************************************/
2082
2083static void doXPathDump(xmlXPathObjectPtr cur) {
2084 switch(cur->type) {
2085 case XPATH_NODESET: {
2086 int i;
2087 xmlNodePtr node;
2088#ifdef LIBXML_OUTPUT_ENABLED
2089 xmlSaveCtxtPtr ctxt;
2090
Daniel Veillardbdc64d62012-03-27 14:41:37 +08002091 if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr <= 0)) {
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002092 fprintf(stderr, "XPath set is empty\n");
2093 progresult = XMLLINT_ERR_XPATH;
2094 break;
2095 }
2096 ctxt = xmlSaveToFd(1, NULL, 0);
2097 if (ctxt == NULL) {
2098 fprintf(stderr, "Out of memory for XPath\n");
2099 progresult = XMLLINT_ERR_MEM;
2100 return;
2101 }
2102 for (i = 0;i < cur->nodesetval->nodeNr;i++) {
2103 node = cur->nodesetval->nodeTab[i];
2104 xmlSaveTree(ctxt, node);
2105 }
2106 xmlSaveClose(ctxt);
2107#else
2108 printf("xpath returned %d nodes\n", cur->nodesetval->nodeNr);
2109#endif
2110 break;
2111 }
2112 case XPATH_BOOLEAN:
2113 if (cur->boolval) printf("true");
2114 else printf("false");
2115 break;
2116 case XPATH_NUMBER:
2117 switch (xmlXPathIsInf(cur->floatval)) {
2118 case 1:
2119 printf("Infinity");
2120 break;
2121 case -1:
2122 printf("-Infinity");
2123 break;
2124 default:
2125 if (xmlXPathIsNaN(cur->floatval)) {
2126 printf("NaN");
2127 } else {
2128 printf("%0g", cur->floatval);
2129 }
2130 }
2131 break;
2132 case XPATH_STRING:
2133 printf("%s", (const char *) cur->stringval);
2134 break;
2135 case XPATH_UNDEFINED:
2136 fprintf(stderr, "XPath Object is uninitialized\n");
2137 progresult = XMLLINT_ERR_XPATH;
2138 break;
2139 default:
2140 fprintf(stderr, "XPath object of unexpected type\n");
2141 progresult = XMLLINT_ERR_XPATH;
2142 break;
2143 }
2144}
2145
2146static void doXPathQuery(xmlDocPtr doc, const char *query) {
2147 xmlXPathContextPtr ctxt;
2148 xmlXPathObjectPtr res;
2149
2150 ctxt = xmlXPathNewContext(doc);
2151 if (ctxt == NULL) {
2152 fprintf(stderr, "Out of memory for XPath\n");
2153 progresult = XMLLINT_ERR_MEM;
2154 return;
2155 }
Daniel Veillard2e1eaca2012-05-25 16:44:20 +08002156 ctxt->node = (xmlNodePtr) doc;
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002157 res = xmlXPathEval(BAD_CAST query, ctxt);
2158 xmlXPathFreeContext(ctxt);
2159
2160 if (res == NULL) {
2161 fprintf(stderr, "XPath evaluation failure\n");
2162 progresult = XMLLINT_ERR_XPATH;
2163 return;
2164 }
2165 doXPathDump(res);
2166 xmlXPathFreeObject(res);
2167}
2168#endif /* LIBXML_XPATH_ENABLED */
2169
Daniel Veillard7704fb12003-01-03 16:19:51 +00002170/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +02002171 * *
2172 * Tree Test processing *
2173 * *
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002174 ************************************************************************/
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002175static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
Daniel Veillard652327a2003-09-29 18:02:38 +00002176 xmlDocPtr doc = NULL;
2177#ifdef LIBXML_TREE_ENABLED
2178 xmlDocPtr tmp;
2179#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002180
Daniel Veillard48b2f892001-02-25 16:11:03 +00002181 if ((timing) && (!repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00002182 startTimer();
Daniel Veillardf1edb102009-08-10 14:43:18 +02002183
Daniel Veillard48b2f892001-02-25 16:11:03 +00002184
Daniel Veillard652327a2003-09-29 18:02:38 +00002185#ifdef LIBXML_TREE_ENABLED
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002186 if (filename == NULL) {
2187 if (generate) {
2188 xmlNodePtr n;
2189
2190 doc = xmlNewDoc(BAD_CAST "1.0");
Daniel Veillard95ddcd32004-10-26 21:53:55 +00002191 n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002192 xmlNodeSetContent(n, BAD_CAST "abc");
2193 xmlDocSetRootElement(doc, n);
2194 }
2195 }
Daniel Veillard652327a2003-09-29 18:02:38 +00002196#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002197#ifdef LIBXML_HTML_ENABLED
Daniel Veillard73b013f2003-09-30 12:36:01 +00002198#ifdef LIBXML_PUSH_ENABLED
William M. Brack78637da2003-07-31 14:47:38 +00002199 else if ((html) && (push)) {
2200 FILE *f;
2201
William M. Brack3403add2004-06-27 02:07:51 +00002202#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2203 f = fopen(filename, "rb");
Patrick Monnerat1c43f432013-12-12 15:12:53 +08002204#elif defined(__OS400__)
2205 f = fopen(filename, "rb");
William M. Brack3403add2004-06-27 02:07:51 +00002206#else
2207 f = fopen(filename, "r");
2208#endif
William M. Brack78637da2003-07-31 14:47:38 +00002209 if (f != NULL) {
Daniel Veillard1abd2212012-10-25 15:37:50 +08002210 int res;
William M. Brack78637da2003-07-31 14:47:38 +00002211 char chars[4096];
2212 htmlParserCtxtPtr ctxt;
2213
William M. Brack78637da2003-07-31 14:47:38 +00002214 res = fread(chars, 1, 4, f);
2215 if (res > 0) {
2216 ctxt = htmlCreatePushParserCtxt(NULL, NULL,
William M. Brack1d75c8a2003-10-27 13:48:16 +00002217 chars, res, filename, XML_CHAR_ENCODING_NONE);
Arnold Hendriks826bc322013-11-29 14:12:12 +08002218 xmlCtxtUseOptions(ctxt, options);
Daniel Veillard1abd2212012-10-25 15:37:50 +08002219 while ((res = fread(chars, 1, pushsize, f)) > 0) {
William M. Brack78637da2003-07-31 14:47:38 +00002220 htmlParseChunk(ctxt, chars, res, 0);
2221 }
2222 htmlParseChunk(ctxt, chars, 0, 1);
2223 doc = ctxt->myDoc;
2224 htmlFreeParserCtxt(ctxt);
2225 }
2226 fclose(f);
2227 }
2228 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00002229#endif /* LIBXML_PUSH_ENABLED */
Daniel Richard G5706b6d2012-08-06 11:32:54 +08002230#ifdef HAVE_MMAP
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002231 else if ((html) && (memory)) {
2232 int fd;
2233 struct stat info;
2234 const char *base;
Daniel Veillardf1edb102009-08-10 14:43:18 +02002235 if (stat(filename, &info) < 0)
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002236 return;
2237 if ((fd = open(filename, O_RDONLY)) < 0)
2238 return;
2239 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillardb98c6a02013-07-12 12:08:40 +08002240 if (base == (void *) MAP_FAILED) {
2241 close(fd);
2242 fprintf(stderr, "mmap failure for file %s\n", filename);
2243 progresult = XMLLINT_ERR_RDFILE;
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002244 return;
Daniel Veillardb98c6a02013-07-12 12:08:40 +08002245 }
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002246
2247 doc = htmlReadMemory((char *) base, info.st_size, filename,
2248 NULL, options);
Daniel Veillardf1edb102009-08-10 14:43:18 +02002249
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002250 munmap((char *) base, info.st_size);
2251 close(fd);
2252 }
2253#endif
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002254 else if (html) {
Daniel Veillard9475a352003-09-26 12:47:50 +00002255 doc = htmlReadFile(filename, NULL, options);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002256 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002257#endif /* LIBXML_HTML_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002258 else {
Daniel Veillard73b013f2003-09-30 12:36:01 +00002259#ifdef LIBXML_PUSH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002260 /*
2261 * build an XML tree from a string;
2262 */
2263 if (push) {
2264 FILE *f;
2265
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002266 /* '-' Usually means stdin -<sven@zen.org> */
2267 if ((filename[0] == '-') && (filename[1] == 0)) {
2268 f = stdin;
2269 } else {
William M. Brack3403add2004-06-27 02:07:51 +00002270#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2271 f = fopen(filename, "rb");
Patrick Monnerat1c43f432013-12-12 15:12:53 +08002272#elif defined(__OS400__)
2273 f = fopen(filename, "rb");
William M. Brack3403add2004-06-27 02:07:51 +00002274#else
2275 f = fopen(filename, "r");
2276#endif
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002277 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002278 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +00002279 int ret;
Daniel Veillarda880b122003-04-21 21:36:41 +00002280 int res, size = 1024;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002281 char chars[1024];
2282 xmlParserCtxtPtr ctxt;
2283
Daniel Veillarda880b122003-04-21 21:36:41 +00002284 /* if (repeat) size = 1024; */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002285 res = fread(chars, 1, 4, f);
2286 if (res > 0) {
2287 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
2288 chars, res, filename);
Daniel Veillard500a1de2004-03-22 15:22:58 +00002289 xmlCtxtUseOptions(ctxt, options);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002290 while ((res = fread(chars, 1, size, f)) > 0) {
2291 xmlParseChunk(ctxt, chars, res, 0);
2292 }
2293 xmlParseChunk(ctxt, chars, 0, 1);
2294 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +00002295 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002296 xmlFreeParserCtxt(ctxt);
Daniel Veillarde715dd22000-08-29 18:29:38 +00002297 if (!ret) {
2298 xmlFreeDoc(doc);
2299 doc = NULL;
2300 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002301 }
Daniel Veillard84bff682009-09-11 15:30:19 +02002302 if (f != stdin)
2303 fclose(f);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002304 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00002305 } else
2306#endif /* LIBXML_PUSH_ENABLED */
2307 if (testIO) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002308 if ((filename[0] == '-') && (filename[1] == 0)) {
Daniel Veillard60942de2003-09-25 21:05:58 +00002309 doc = xmlReadFd(0, NULL, NULL, options);
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002310 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002311 FILE *f;
Daniel Veillard5e873c42000-04-12 13:27:38 +00002312
William M. Brack3403add2004-06-27 02:07:51 +00002313#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2314 f = fopen(filename, "rb");
Patrick Monnerat1c43f432013-12-12 15:12:53 +08002315#elif defined(__OS400__)
2316 f = fopen(filename, "rb");
William M. Brack3403add2004-06-27 02:07:51 +00002317#else
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002318 f = fopen(filename, "r");
William M. Brack3403add2004-06-27 02:07:51 +00002319#endif
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002320 if (f != NULL) {
2321 if (rectxt == NULL)
2322 doc = xmlReadIO((xmlInputReadCallback) myRead,
2323 (xmlInputCloseCallback) myClose, f,
Daniel Veillard60942de2003-09-25 21:05:58 +00002324 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002325 else
2326 doc = xmlCtxtReadIO(rectxt,
2327 (xmlInputReadCallback) myRead,
2328 (xmlInputCloseCallback) myClose, f,
Daniel Veillard60942de2003-09-25 21:05:58 +00002329 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002330 } else
Daniel Veillard5e873c42000-04-12 13:27:38 +00002331 doc = NULL;
Daniel Veillard5e873c42000-04-12 13:27:38 +00002332 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002333 } else if (htmlout) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002334 xmlParserCtxtPtr ctxt;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002335
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002336 if (rectxt == NULL)
2337 ctxt = xmlNewParserCtxt();
2338 else
2339 ctxt = rectxt;
Daniel Veillardf1edb102009-08-10 14:43:18 +02002340 if (ctxt == NULL) {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002341 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +00002342 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002343 ctxt->sax->error = xmlHTMLError;
2344 ctxt->sax->warning = xmlHTMLWarning;
2345 ctxt->vctxt.error = xmlHTMLValidityError;
2346 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002347
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002348 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002349
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002350 if (rectxt == NULL)
2351 xmlFreeParserCtxt(ctxt);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002352 }
Daniel Richard G5706b6d2012-08-06 11:32:54 +08002353#ifdef HAVE_MMAP
Daniel Veillard46e370e2000-07-21 20:32:03 +00002354 } else if (memory) {
2355 int fd;
2356 struct stat info;
2357 const char *base;
Daniel Veillardf1edb102009-08-10 14:43:18 +02002358 if (stat(filename, &info) < 0)
Daniel Veillard46e370e2000-07-21 20:32:03 +00002359 return;
2360 if ((fd = open(filename, O_RDONLY)) < 0)
2361 return;
2362 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillarda75a0092013-05-08 13:45:48 +08002363 if (base == (void *) MAP_FAILED) {
Daniel Veillardb98c6a02013-07-12 12:08:40 +08002364 close(fd);
Daniel Veillarda75a0092013-05-08 13:45:48 +08002365 fprintf(stderr, "mmap failure for file %s\n", filename);
2366 progresult = XMLLINT_ERR_RDFILE;
Daniel Veillard46e370e2000-07-21 20:32:03 +00002367 return;
Daniel Veillarda75a0092013-05-08 13:45:48 +08002368 }
Daniel Veillard46e370e2000-07-21 20:32:03 +00002369
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002370 if (rectxt == NULL)
Daniel Veillard60942de2003-09-25 21:05:58 +00002371 doc = xmlReadMemory((char *) base, info.st_size,
2372 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002373 else
Daniel Veillard60942de2003-09-25 21:05:58 +00002374 doc = xmlCtxtReadMemory(rectxt, (char *) base, info.st_size,
2375 filename, NULL, options);
Daniel Veillardf1edb102009-08-10 14:43:18 +02002376
Daniel Veillard46e370e2000-07-21 20:32:03 +00002377 munmap((char *) base, info.st_size);
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002378 close(fd);
Daniel Veillard46e370e2000-07-21 20:32:03 +00002379#endif
Daniel Veillard4432df22003-09-28 18:58:27 +00002380#ifdef LIBXML_VALID_ENABLED
Daniel Veillardea7751d2002-12-20 00:16:24 +00002381 } else if (valid) {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002382 xmlParserCtxtPtr ctxt = NULL;
Daniel Veillardea7751d2002-12-20 00:16:24 +00002383
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002384 if (rectxt == NULL)
2385 ctxt = xmlNewParserCtxt();
2386 else
2387 ctxt = rectxt;
Daniel Veillardf1edb102009-08-10 14:43:18 +02002388 if (ctxt == NULL) {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002389 doc = NULL;
Daniel Veillardea7751d2002-12-20 00:16:24 +00002390 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002391 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
2392
2393 if (ctxt->valid == 0)
William M. Brack8304d872004-06-08 13:29:32 +00002394 progresult = XMLLINT_ERR_RDFILE;
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002395 if (rectxt == NULL)
2396 xmlFreeParserCtxt(ctxt);
Daniel Veillardea7751d2002-12-20 00:16:24 +00002397 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002398#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardea7751d2002-12-20 00:16:24 +00002399 } else {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002400 if (rectxt != NULL)
2401 doc = xmlCtxtReadFile(rectxt, filename, NULL, options);
Daniel Veillard81562d22005-06-15 13:27:56 +00002402 else {
2403#ifdef LIBXML_SAX1_ENABLED
2404 if (sax1)
2405 doc = xmlParseFile(filename);
2406 else
2407#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002408 doc = xmlReadFile(filename, NULL, options);
Daniel Veillard81562d22005-06-15 13:27:56 +00002409 }
Daniel Veillardea7751d2002-12-20 00:16:24 +00002410 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002411 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002412
Daniel Veillard88a172f2000-08-04 18:23:10 +00002413 /*
2414 * If we don't have a document we might as well give up. Do we
2415 * want an error message here? <sven@zen.org> */
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002416 if (doc == NULL) {
William M. Brack8304d872004-06-08 13:29:32 +00002417 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard88a172f2000-08-04 18:23:10 +00002418 return;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002419 }
2420
Daniel Veillard48b2f892001-02-25 16:11:03 +00002421 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002422 endTimer("Parsing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002423 }
2424
Daniel Veillard29e43992001-12-13 22:21:58 +00002425 /*
2426 * Remove DOCTYPE nodes
2427 */
2428 if (dropdtd) {
2429 xmlDtdPtr dtd;
2430
2431 dtd = xmlGetIntSubset(doc);
2432 if (dtd != NULL) {
2433 xmlUnlinkNode((xmlNodePtr)dtd);
2434 xmlFreeDtd(dtd);
2435 }
2436 }
2437
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002438#ifdef LIBXML_XINCLUDE_ENABLED
Daniel Veillard48b2f892001-02-25 16:11:03 +00002439 if (xinclude) {
2440 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002441 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002442 }
William M. Brack4e1c2db2005-02-11 10:58:55 +00002443 if (xmlXIncludeProcessFlags(doc, options) < 0)
2444 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard48b2f892001-02-25 16:11:03 +00002445 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002446 endTimer("Xinclude processing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002447 }
2448 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002449#endif
Daniel Veillard88a172f2000-08-04 18:23:10 +00002450
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002451#ifdef LIBXML_XPATH_ENABLED
2452 if (xpathquery != NULL) {
2453 doXPathQuery(doc, xpathquery);
2454 }
2455#endif
2456
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002457#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00002458#ifdef LIBXML_XPATH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002459 /*
Daniel Veillardcbaf3992001-12-31 16:16:02 +00002460 * shell interaction
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002461 */
Daniel Veillard26a45c82006-10-20 12:55:34 +00002462 if (shell) {
2463 xmlXPathOrderDocElems(doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002464 xmlShell(doc, filename, xmlShellReadline, stdout);
Daniel Veillard26a45c82006-10-20 12:55:34 +00002465 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002466#endif
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00002467#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002468
Daniel Veillard652327a2003-09-29 18:02:38 +00002469#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002470 /*
2471 * test intermediate copy if needed.
2472 */
2473 if (copy) {
2474 tmp = doc;
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002475 if (timing) {
2476 startTimer();
2477 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002478 doc = xmlCopyDoc(doc, 1);
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002479 if (timing) {
2480 endTimer("Copying");
2481 }
2482 if (timing) {
2483 startTimer();
2484 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002485 xmlFreeDoc(tmp);
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002486 if (timing) {
2487 endTimer("Freeing original");
2488 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002489 }
Daniel Veillard652327a2003-09-29 18:02:38 +00002490#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002491
Daniel Veillard4432df22003-09-28 18:58:27 +00002492#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002493 if ((insert) && (!html)) {
2494 const xmlChar* list[256];
2495 int nb, i;
2496 xmlNodePtr node;
2497
2498 if (doc->children != NULL) {
2499 node = doc->children;
2500 while ((node != NULL) && (node->last == NULL)) node = node->next;
2501 if (node != NULL) {
2502 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
2503 if (nb < 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002504 fprintf(stderr, "could not get valid list of elements\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002505 } else if (nb == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002506 fprintf(stderr, "No element can be inserted under root\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002507 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002508 fprintf(stderr, "%d element types can be inserted under root:\n",
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002509 nb);
2510 for (i = 0;i < nb;i++) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002511 fprintf(stderr, "%s\n", (char *) list[i]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002512 }
2513 }
2514 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02002515 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002516 }else
2517#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002518#ifdef LIBXML_READER_ENABLED
2519 if (walker) {
2520 walkDoc(doc);
2521 }
2522#endif /* LIBXML_READER_ENABLED */
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002523#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard4432df22003-09-28 18:58:27 +00002524 if (noout == 0) {
Daniel Veillard3df01182003-12-10 10:17:51 +00002525 int ret;
2526
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002527 /*
2528 * print it.
2529 */
2530#ifdef LIBXML_DEBUG_ENABLED
2531 if (!debug) {
2532#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00002533 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002534 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002535 }
Daniel Veillard656ce942004-04-30 23:11:45 +00002536#ifdef LIBXML_HTML_ENABLED
Daniel Veillard42fd4122003-11-04 08:47:48 +00002537 if ((html) && (!xmlout)) {
2538 if (compress) {
2539 htmlSaveFile(output ? output : "-", doc);
2540 }
2541 else if (encoding != NULL) {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002542 if (format == 1) {
Daniel Veillard42fd4122003-11-04 08:47:48 +00002543 htmlSaveFileFormat(output ? output : "-", doc, encoding, 1);
2544 }
2545 else {
2546 htmlSaveFileFormat(output ? output : "-", doc, encoding, 0);
2547 }
2548 }
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002549 else if (format == 1) {
Daniel Veillard42fd4122003-11-04 08:47:48 +00002550 htmlSaveFileFormat(output ? output : "-", doc, NULL, 1);
2551 }
2552 else {
2553 FILE *out;
2554 if (output == NULL)
2555 out = stdout;
2556 else {
2557 out = fopen(output,"wb");
2558 }
2559 if (out != NULL) {
2560 if (htmlDocDump(out, doc) < 0)
William M. Brack8304d872004-06-08 13:29:32 +00002561 progresult = XMLLINT_ERR_OUT;
Daniel Veillard42fd4122003-11-04 08:47:48 +00002562
2563 if (output != NULL)
2564 fclose(out);
2565 } else {
2566 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00002567 progresult = XMLLINT_ERR_OUT;
Daniel Veillard42fd4122003-11-04 08:47:48 +00002568 }
2569 }
2570 if ((timing) && (!repeat)) {
2571 endTimer("Saving");
2572 }
2573 } else
2574#endif
Daniel Veillard25048d82004-08-14 22:37:54 +00002575#ifdef LIBXML_C14N_ENABLED
2576 if (canonical) {
2577 xmlChar *result = NULL;
2578 int size;
2579
Aleksey Sanin83868242009-07-09 10:26:22 +02002580 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_0, NULL, 1, &result);
2581 if (size >= 0) {
Stefan Kostdff8d0f2011-05-09 12:14:59 +03002582 if (write(1, result, size) == -1) {
2583 fprintf(stderr, "Can't write data\n");
2584 }
Aleksey Sanin83868242009-07-09 10:26:22 +02002585 xmlFree(result);
2586 } else {
2587 fprintf(stderr, "Failed to canonicalize\n");
2588 progresult = XMLLINT_ERR_OUT;
2589 }
Sérgio Batistad9ea9132014-06-09 22:10:15 +08002590 } else if (canonical_11) {
Aleksey Sanin83868242009-07-09 10:26:22 +02002591 xmlChar *result = NULL;
2592 int size;
2593
2594 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_1, NULL, 1, &result);
Daniel Veillard25048d82004-08-14 22:37:54 +00002595 if (size >= 0) {
Stefan Kostdff8d0f2011-05-09 12:14:59 +03002596 if (write(1, result, size) == -1) {
2597 fprintf(stderr, "Can't write data\n");
2598 }
Daniel Veillard25048d82004-08-14 22:37:54 +00002599 xmlFree(result);
2600 } else {
2601 fprintf(stderr, "Failed to canonicalize\n");
2602 progresult = XMLLINT_ERR_OUT;
2603 }
2604 } else
Aleksey Sanin2650df12005-06-06 17:16:50 +00002605 if (exc_canonical) {
2606 xmlChar *result = NULL;
2607 int size;
2608
Aleksey Sanin83868242009-07-09 10:26:22 +02002609 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_EXCLUSIVE_1_0, NULL, 1, &result);
Aleksey Sanin2650df12005-06-06 17:16:50 +00002610 if (size >= 0) {
Stefan Kostdff8d0f2011-05-09 12:14:59 +03002611 if (write(1, result, size) == -1) {
2612 fprintf(stderr, "Can't write data\n");
2613 }
Aleksey Sanin2650df12005-06-06 17:16:50 +00002614 xmlFree(result);
2615 } else {
2616 fprintf(stderr, "Failed to canonicalize\n");
2617 progresult = XMLLINT_ERR_OUT;
2618 }
2619 } else
Daniel Veillard25048d82004-08-14 22:37:54 +00002620#endif
Daniel Richard G5706b6d2012-08-06 11:32:54 +08002621#ifdef HAVE_MMAP
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002622 if (memory) {
2623 xmlChar *result;
2624 int len;
2625
2626 if (encoding != NULL) {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002627 if (format == 1) {
Daniel Veillardd536f702001-11-08 17:32:47 +00002628 xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
Daniel Veillardf1edb102009-08-10 14:43:18 +02002629 } else {
Daniel Veillardd536f702001-11-08 17:32:47 +00002630 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
2631 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002632 } else {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002633 if (format == 1)
Daniel Veillard90493a92001-08-14 14:12:47 +00002634 xmlDocDumpFormatMemory(doc, &result, &len, 1);
2635 else
2636 xmlDocDumpMemory(doc, &result, &len);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002637 }
2638 if (result == NULL) {
2639 fprintf(stderr, "Failed to save\n");
Daniel Veillard25048d82004-08-14 22:37:54 +00002640 progresult = XMLLINT_ERR_OUT;
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002641 } else {
Stefan Kostdff8d0f2011-05-09 12:14:59 +03002642 if (write(1, result, len) == -1) {
2643 fprintf(stderr, "Can't write data\n");
2644 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002645 xmlFree(result);
2646 }
Daniel Veillarddab39b52006-10-16 23:22:10 +00002647
Daniel Veillard3b2c2612001-04-04 00:09:00 +00002648 } else
Daniel Richard G5706b6d2012-08-06 11:32:54 +08002649#endif /* HAVE_MMAP */
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002650 if (compress) {
2651 xmlSaveFile(output ? output : "-", doc);
Daniel Veillarddab39b52006-10-16 23:22:10 +00002652 } else if (oldout) {
2653 if (encoding != NULL) {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002654 if (format == 1) {
Daniel Veillarddab39b52006-10-16 23:22:10 +00002655 ret = xmlSaveFormatFileEnc(output ? output : "-", doc,
2656 encoding, 1);
2657 }
2658 else {
2659 ret = xmlSaveFileEnc(output ? output : "-", doc,
2660 encoding);
2661 }
2662 if (ret < 0) {
2663 fprintf(stderr, "failed save to %s\n",
2664 output ? output : "-");
2665 progresult = XMLLINT_ERR_OUT;
2666 }
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002667 } else if (format == 1) {
Daniel Veillarddab39b52006-10-16 23:22:10 +00002668 ret = xmlSaveFormatFile(output ? output : "-", doc, 1);
2669 if (ret < 0) {
2670 fprintf(stderr, "failed save to %s\n",
2671 output ? output : "-");
2672 progresult = XMLLINT_ERR_OUT;
2673 }
Daniel Veillard05d987b2003-10-08 11:54:57 +00002674 } else {
Daniel Veillarddab39b52006-10-16 23:22:10 +00002675 FILE *out;
2676 if (output == NULL)
2677 out = stdout;
2678 else {
2679 out = fopen(output,"wb");
2680 }
2681 if (out != NULL) {
2682 if (xmlDocDump(out, doc) < 0)
2683 progresult = XMLLINT_ERR_OUT;
2684
2685 if (output != NULL)
2686 fclose(out);
2687 } else {
2688 fprintf(stderr, "failed to open %s\n", output);
2689 progresult = XMLLINT_ERR_OUT;
2690 }
2691 }
2692 } else {
2693 xmlSaveCtxtPtr ctxt;
2694 int saveOpts = 0;
2695
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002696 if (format == 1)
Daniel Veillarddab39b52006-10-16 23:22:10 +00002697 saveOpts |= XML_SAVE_FORMAT;
Adam Spraggd2e62312010-11-03 15:33:40 +01002698 else if (format == 2)
2699 saveOpts |= XML_SAVE_WSNONSIG;
Daniel Veillard9ccea572010-03-10 15:02:49 +01002700
2701#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
Daniel Veillard9d962642009-08-23 15:31:18 +02002702 if (xmlout)
2703 saveOpts |= XML_SAVE_AS_XML;
Daniel Veillard9ccea572010-03-10 15:02:49 +01002704#endif
Daniel Veillarddab39b52006-10-16 23:22:10 +00002705
2706 if (output == NULL)
2707 ctxt = xmlSaveToFd(1, encoding, saveOpts);
2708 else
2709 ctxt = xmlSaveToFilename(output, encoding, saveOpts);
2710
2711 if (ctxt != NULL) {
2712 if (xmlSaveDoc(ctxt, doc) < 0) {
2713 fprintf(stderr, "failed save to %s\n",
2714 output ? output : "-");
2715 progresult = XMLLINT_ERR_OUT;
2716 }
2717 xmlSaveClose(ctxt);
2718 } else {
William M. Brack8304d872004-06-08 13:29:32 +00002719 progresult = XMLLINT_ERR_OUT;
Daniel Veillard05d987b2003-10-08 11:54:57 +00002720 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002721 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002722 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002723 endTimer("Saving");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002724 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002725#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002726 } else {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002727 FILE *out;
2728 if (output == NULL)
2729 out = stdout;
2730 else {
2731 out = fopen(output,"wb");
2732 }
Daniel Veillard05d987b2003-10-08 11:54:57 +00002733 if (out != NULL) {
2734 xmlDebugDumpDocument(out, doc);
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002735
Daniel Veillard05d987b2003-10-08 11:54:57 +00002736 if (output != NULL)
2737 fclose(out);
2738 } else {
2739 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00002740 progresult = XMLLINT_ERR_OUT;
Daniel Veillard05d987b2003-10-08 11:54:57 +00002741 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002742 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002743#endif
2744 }
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002745#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002746
Daniel Veillard4432df22003-09-28 18:58:27 +00002747#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002748 /*
2749 * A posteriori validation test
2750 */
Daniel Veillard66f68e72003-08-18 16:39:51 +00002751 if ((dtdvalid != NULL) || (dtdvalidfpi != NULL)) {
Daniel Veillardcd429612000-10-11 15:57:05 +00002752 xmlDtdPtr dtd;
2753
Daniel Veillard48b2f892001-02-25 16:11:03 +00002754 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002755 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002756 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00002757 if (dtdvalid != NULL)
Daniel Veillardf1edb102009-08-10 14:43:18 +02002758 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
Daniel Veillard66f68e72003-08-18 16:39:51 +00002759 else
Daniel Veillardf1edb102009-08-10 14:43:18 +02002760 dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL);
Daniel Veillard48b2f892001-02-25 16:11:03 +00002761 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002762 endTimer("Parsing DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002763 }
Daniel Veillardcd429612000-10-11 15:57:05 +00002764 if (dtd == NULL) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00002765 if (dtdvalid != NULL)
2766 xmlGenericError(xmlGenericErrorContext,
2767 "Could not parse DTD %s\n", dtdvalid);
2768 else
2769 xmlGenericError(xmlGenericErrorContext,
2770 "Could not parse DTD %s\n", dtdvalidfpi);
William M. Brack8304d872004-06-08 13:29:32 +00002771 progresult = XMLLINT_ERR_DTD;
Daniel Veillardcd429612000-10-11 15:57:05 +00002772 } else {
Daniel Veillarda37aab82003-06-09 09:10:36 +00002773 xmlValidCtxtPtr cvp;
2774
2775 if ((cvp = xmlNewValidCtxt()) == NULL) {
2776 xmlGenericError(xmlGenericErrorContext,
2777 "Couldn't allocate validation context\n");
2778 exit(-1);
2779 }
2780 cvp->userData = (void *) stderr;
2781 cvp->error = (xmlValidityErrorFunc) fprintf;
2782 cvp->warning = (xmlValidityWarningFunc) fprintf;
2783
Daniel Veillard48b2f892001-02-25 16:11:03 +00002784 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002785 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002786 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002787 if (!xmlValidateDtd(cvp, doc, dtd)) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00002788 if (dtdvalid != NULL)
2789 xmlGenericError(xmlGenericErrorContext,
2790 "Document %s does not validate against %s\n",
2791 filename, dtdvalid);
2792 else
2793 xmlGenericError(xmlGenericErrorContext,
2794 "Document %s does not validate against %s\n",
2795 filename, dtdvalidfpi);
William M. Brack8304d872004-06-08 13:29:32 +00002796 progresult = XMLLINT_ERR_VALID;
Daniel Veillardcd429612000-10-11 15:57:05 +00002797 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002798 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002799 endTimer("Validating against DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002800 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002801 xmlFreeValidCtxt(cvp);
Daniel Veillardcd429612000-10-11 15:57:05 +00002802 xmlFreeDtd(dtd);
2803 }
2804 } else if (postvalid) {
Daniel Veillarda37aab82003-06-09 09:10:36 +00002805 xmlValidCtxtPtr cvp;
2806
2807 if ((cvp = xmlNewValidCtxt()) == NULL) {
2808 xmlGenericError(xmlGenericErrorContext,
2809 "Couldn't allocate validation context\n");
2810 exit(-1);
2811 }
2812
Daniel Veillard48b2f892001-02-25 16:11:03 +00002813 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002814 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002815 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002816 cvp->userData = (void *) stderr;
2817 cvp->error = (xmlValidityErrorFunc) fprintf;
2818 cvp->warning = (xmlValidityWarningFunc) fprintf;
2819 if (!xmlValidateDocument(cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00002820 xmlGenericError(xmlGenericErrorContext,
2821 "Document %s does not validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002822 progresult = XMLLINT_ERR_VALID;
Daniel Veillardcd429612000-10-11 15:57:05 +00002823 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002824 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002825 endTimer("Validating");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002826 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002827 xmlFreeValidCtxt(cvp);
Daniel Veillard4432df22003-09-28 18:58:27 +00002828 }
2829#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardd4501d72005-07-24 14:27:16 +00002830#ifdef LIBXML_SCHEMATRON_ENABLED
2831 if (wxschematron != NULL) {
2832 xmlSchematronValidCtxtPtr ctxt;
2833 int ret;
Daniel Veillardc740a172005-07-31 12:17:24 +00002834 int flag;
Daniel Veillardd4501d72005-07-24 14:27:16 +00002835
2836 if ((timing) && (!repeat)) {
2837 startTimer();
2838 }
2839
2840 if (debug)
2841 flag = XML_SCHEMATRON_OUT_XML;
Daniel Veillardc740a172005-07-31 12:17:24 +00002842 else
2843 flag = XML_SCHEMATRON_OUT_TEXT;
2844 if (noout)
2845 flag |= XML_SCHEMATRON_OUT_QUIET;
Daniel Veillardd4501d72005-07-24 14:27:16 +00002846 ctxt = xmlSchematronNewValidCtxt(wxschematron, flag);
2847#if 0
2848 xmlSchematronSetValidErrors(ctxt,
2849 (xmlSchematronValidityErrorFunc) fprintf,
2850 (xmlSchematronValidityWarningFunc) fprintf,
2851 stderr);
2852#endif
2853 ret = xmlSchematronValidateDoc(ctxt, doc);
2854 if (ret == 0) {
2855 fprintf(stderr, "%s validates\n", filename);
2856 } else if (ret > 0) {
2857 fprintf(stderr, "%s fails to validate\n", filename);
2858 progresult = XMLLINT_ERR_VALID;
2859 } else {
2860 fprintf(stderr, "%s validation generated an internal error\n",
2861 filename);
2862 progresult = XMLLINT_ERR_VALID;
2863 }
2864 xmlSchematronFreeValidCtxt(ctxt);
2865 if ((timing) && (!repeat)) {
2866 endTimer("Validating");
2867 }
2868 }
2869#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00002870#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard4432df22003-09-28 18:58:27 +00002871 if (relaxngschemas != NULL) {
Daniel Veillard71531f32003-02-05 13:19:53 +00002872 xmlRelaxNGValidCtxtPtr ctxt;
2873 int ret;
2874
Daniel Veillard42f12e92003-03-07 18:32:59 +00002875 if ((timing) && (!repeat)) {
2876 startTimer();
2877 }
2878
Daniel Veillard71531f32003-02-05 13:19:53 +00002879 ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
2880 xmlRelaxNGSetValidErrors(ctxt,
2881 (xmlRelaxNGValidityErrorFunc) fprintf,
2882 (xmlRelaxNGValidityWarningFunc) fprintf,
2883 stderr);
2884 ret = xmlRelaxNGValidateDoc(ctxt, doc);
2885 if (ret == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002886 fprintf(stderr, "%s validates\n", filename);
Daniel Veillard71531f32003-02-05 13:19:53 +00002887 } else if (ret > 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002888 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002889 progresult = XMLLINT_ERR_VALID;
Daniel Veillard71531f32003-02-05 13:19:53 +00002890 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002891 fprintf(stderr, "%s validation generated an internal error\n",
Daniel Veillard71531f32003-02-05 13:19:53 +00002892 filename);
William M. Brack8304d872004-06-08 13:29:32 +00002893 progresult = XMLLINT_ERR_VALID;
Daniel Veillard71531f32003-02-05 13:19:53 +00002894 }
2895 xmlRelaxNGFreeValidCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00002896 if ((timing) && (!repeat)) {
2897 endTimer("Validating");
2898 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002899 } else if (wxschemas != NULL) {
2900 xmlSchemaValidCtxtPtr ctxt;
2901 int ret;
2902
2903 if ((timing) && (!repeat)) {
2904 startTimer();
2905 }
2906
2907 ctxt = xmlSchemaNewValidCtxt(wxschemas);
2908 xmlSchemaSetValidErrors(ctxt,
2909 (xmlSchemaValidityErrorFunc) fprintf,
2910 (xmlSchemaValidityWarningFunc) fprintf,
2911 stderr);
2912 ret = xmlSchemaValidateDoc(ctxt, doc);
2913 if (ret == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002914 fprintf(stderr, "%s validates\n", filename);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002915 } else if (ret > 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002916 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002917 progresult = XMLLINT_ERR_VALID;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002918 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002919 fprintf(stderr, "%s validation generated an internal error\n",
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002920 filename);
William M. Brack8304d872004-06-08 13:29:32 +00002921 progresult = XMLLINT_ERR_VALID;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002922 }
2923 xmlSchemaFreeValidCtxt(ctxt);
2924 if ((timing) && (!repeat)) {
2925 endTimer("Validating");
2926 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002927 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002928#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002929
2930#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillard6b099012008-11-06 13:47:39 +00002931#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002932 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00002933 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002934#endif
Daniel Veillard6b099012008-11-06 13:47:39 +00002935#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002936
2937 /*
2938 * free it.
2939 */
Daniel Veillard48b2f892001-02-25 16:11:03 +00002940 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002941 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002942 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002943 xmlFreeDoc(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +00002944 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002945 endTimer("Freeing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002946 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002947}
2948
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002949/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +02002950 * *
2951 * Usage and Main *
2952 * *
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002953 ************************************************************************/
2954
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002955static void showVersion(const char *name) {
2956 fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
2957 fprintf(stderr, " compiled with: ");
Daniel Veillard602434d2005-09-12 09:20:31 +00002958 if (xmlHasFeature(XML_WITH_THREAD)) fprintf(stderr, "Threads ");
2959 if (xmlHasFeature(XML_WITH_TREE)) fprintf(stderr, "Tree ");
2960 if (xmlHasFeature(XML_WITH_OUTPUT)) fprintf(stderr, "Output ");
2961 if (xmlHasFeature(XML_WITH_PUSH)) fprintf(stderr, "Push ");
2962 if (xmlHasFeature(XML_WITH_READER)) fprintf(stderr, "Reader ");
2963 if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(stderr, "Patterns ");
2964 if (xmlHasFeature(XML_WITH_WRITER)) fprintf(stderr, "Writer ");
2965 if (xmlHasFeature(XML_WITH_SAX1)) fprintf(stderr, "SAXv1 ");
Daniel Veillardf1edb102009-08-10 14:43:18 +02002966 if (xmlHasFeature(XML_WITH_FTP)) fprintf(stderr, "FTP ");
2967 if (xmlHasFeature(XML_WITH_HTTP)) fprintf(stderr, "HTTP ");
Daniel Veillard602434d2005-09-12 09:20:31 +00002968 if (xmlHasFeature(XML_WITH_VALID)) fprintf(stderr, "DTDValid ");
Daniel Veillardf1edb102009-08-10 14:43:18 +02002969 if (xmlHasFeature(XML_WITH_HTML)) fprintf(stderr, "HTML ");
2970 if (xmlHasFeature(XML_WITH_LEGACY)) fprintf(stderr, "Legacy ");
2971 if (xmlHasFeature(XML_WITH_C14N)) fprintf(stderr, "C14N ");
2972 if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(stderr, "Catalog ");
2973 if (xmlHasFeature(XML_WITH_XPATH)) fprintf(stderr, "XPath ");
2974 if (xmlHasFeature(XML_WITH_XPTR)) fprintf(stderr, "XPointer ");
2975 if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(stderr, "XInclude ");
2976 if (xmlHasFeature(XML_WITH_ICONV)) fprintf(stderr, "Iconv ");
David Kilzer783931f2016-03-02 12:48:51 -08002977 if (xmlHasFeature(XML_WITH_ICU)) fprintf(stderr, "ICU ");
Daniel Veillardf1edb102009-08-10 14:43:18 +02002978 if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(stderr, "ISO8859X ");
2979 if (xmlHasFeature(XML_WITH_UNICODE)) fprintf(stderr, "Unicode ");
2980 if (xmlHasFeature(XML_WITH_REGEXP)) fprintf(stderr, "Regexps ");
2981 if (xmlHasFeature(XML_WITH_AUTOMATA)) fprintf(stderr, "Automata ");
2982 if (xmlHasFeature(XML_WITH_EXPR)) fprintf(stderr, "Expr ");
2983 if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(stderr, "Schemas ");
2984 if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(stderr, "Schematron ");
2985 if (xmlHasFeature(XML_WITH_MODULES)) fprintf(stderr, "Modules ");
2986 if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(stderr, "Debug ");
2987 if (xmlHasFeature(XML_WITH_DEBUG_MEM)) fprintf(stderr, "MemDebug ");
2988 if (xmlHasFeature(XML_WITH_DEBUG_RUN)) fprintf(stderr, "RunDebug ");
Daniel Veillard75acfee2006-07-13 06:29:56 +00002989 if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(stderr, "Zlib ");
Anders F Bjorklundeae52612011-09-18 16:59:13 +02002990 if (xmlHasFeature(XML_WITH_LZMA)) fprintf(stderr, "Lzma ");
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002991 fprintf(stderr, "\n");
2992}
2993
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002994static void usage(const char *name) {
2995 printf("Usage : %s [options] XMLfiles ...\n", name);
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002996#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002997 printf("\tParse the XML files and output the result of the parsing\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002998#else
2999 printf("\tParse the XML files\n");
3000#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003001 printf("\t--version : display the version of the XML library used\n");
3002#ifdef LIBXML_DEBUG_ENABLED
3003 printf("\t--debug : dump a debug tree of the in-memory document\n");
3004 printf("\t--shell : run a navigating shell\n");
3005 printf("\t--debugent : debug the entities defined in the document\n");
Daniel Veillard8326e732003-01-07 00:19:07 +00003006#else
Daniel Veillard81273902003-09-30 00:43:48 +00003007#ifdef LIBXML_READER_ENABLED
Daniel Veillard8326e732003-01-07 00:19:07 +00003008 printf("\t--debug : dump the nodes content when using --stream\n");
Daniel Veillard81273902003-09-30 00:43:48 +00003009#endif /* LIBXML_READER_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003010#endif
Daniel Veillard652327a2003-09-29 18:02:38 +00003011#ifdef LIBXML_TREE_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003012 printf("\t--copy : used to test the internal copy implementation\n");
Daniel Veillard652327a2003-09-29 18:02:38 +00003013#endif /* LIBXML_TREE_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003014 printf("\t--recover : output what was parsable on broken XML documents\n");
Daniel Veillard8915c152008-08-26 13:05:34 +00003015 printf("\t--huge : remove any internal arbitrary parser limits\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003016 printf("\t--noent : substitute entity references by their value\n");
Daniel Veillardc62efc82011-05-16 16:03:50 +08003017 printf("\t--noenc : ignore any encoding specified inside the document\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003018 printf("\t--noout : don't output the result tree\n");
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003019 printf("\t--path 'paths': provide a set of paths for resources\n");
Jan Pokorný9a85d402013-11-29 23:26:25 +01003020 printf("\t--load-trace : print trace of all external entities loaded\n");
Daniel Veillarde8b09e42003-05-13 22:14:13 +00003021 printf("\t--nonet : refuse to fetch DTDs or entities over network\n");
Doran Moppert23040782017-04-07 16:45:56 +02003022 printf("\t--noxxe : forbid any external entity loading\n");
Daniel Veillard8874b942005-08-25 13:19:21 +00003023 printf("\t--nocompact : do not generate compact text nodes\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003024 printf("\t--htmlout : output results as HTML\n");
Daniel Veillard05c13a22001-09-09 08:38:09 +00003025 printf("\t--nowrap : do not put HTML doc wrapper\n");
Daniel Veillard4432df22003-09-28 18:58:27 +00003026#ifdef LIBXML_VALID_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003027 printf("\t--valid : validate the document in addition to std well-formed check\n");
3028 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
3029 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
Daniel Veillard66f68e72003-08-18 16:39:51 +00003030 printf("\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
Daniel Veillard4432df22003-09-28 18:58:27 +00003031#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003032 printf("\t--timing : print some timings\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003033 printf("\t--output file or -o file: save to a given file\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003034 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
3035 printf("\t--insert : ad-hoc test for valid insertions\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003036#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003037#ifdef HAVE_ZLIB_H
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003038 printf("\t--compress : turn on gzip compression of output\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003039#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003040#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003041#ifdef LIBXML_HTML_ENABLED
3042 printf("\t--html : use the HTML parser\n");
Daniel Veillard42fd4122003-11-04 08:47:48 +00003043 printf("\t--xmlout : force to use the XML serializer when using --html\n");
Daniel Veillardf1121c42010-07-26 14:02:42 +02003044 printf("\t--nodefdtd : do not default HTML doctype\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003045#endif
Daniel Veillard73b013f2003-09-30 12:36:01 +00003046#ifdef LIBXML_PUSH_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003047 printf("\t--push : use the push mode of the parser\n");
Daniel Veillard1abd2212012-10-25 15:37:50 +08003048 printf("\t--pushsmall : use the push mode of the parser using tiny increments\n");
Daniel Veillard73b013f2003-09-30 12:36:01 +00003049#endif /* LIBXML_PUSH_ENABLED */
Daniel Richard G5706b6d2012-08-06 11:32:54 +08003050#ifdef HAVE_MMAP
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003051 printf("\t--memory : parse from memory\n");
3052#endif
Daniel Veillard87076042004-05-03 22:54:49 +00003053 printf("\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003054 printf("\t--nowarning : do not emit warnings from parser/validator\n");
3055 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
Daniel Veillarddca8cc72003-09-26 13:53:14 +00003056 printf("\t--nocdata : replace cdata section with text nodes\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003057#ifdef LIBXML_OUTPUT_ENABLED
Fabien Degommeb40c1942015-10-23 19:35:02 +08003058 printf("\t--format : reformat/reindent the output\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003059 printf("\t--encode encoding : output in the given encoding\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003060 printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
Adam Spraggd2e62312010-11-03 15:33:40 +01003061 printf("\t--pretty STYLE : pretty-print in a particular style\n");
3062 printf("\t 0 Do not pretty print\n");
3063 printf("\t 1 Format the XML content, as --format\n");
3064 printf("\t 2 Add whitespace inside tags, preserving content\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003065#endif /* LIBXML_OUTPUT_ENABLED */
Aleksey Sanin83868242009-07-09 10:26:22 +02003066 printf("\t--c14n : save in W3C canonical format v1.0 (with comments)\n");
3067 printf("\t--c14n11 : save in W3C canonical format v1.1 (with comments)\n");
Aleksey Sanin2650df12005-06-06 17:16:50 +00003068 printf("\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n");
Daniel Veillard25048d82004-08-14 22:37:54 +00003069#ifdef LIBXML_C14N_ENABLED
3070#endif /* LIBXML_C14N_ENABLED */
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003071 printf("\t--nsclean : remove redundant namespace declarations\n");
3072 printf("\t--testIO : test user I/O support\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003073#ifdef LIBXML_CATALOG_ENABLED
Daniel Veillardbd9b0e82001-11-26 10:32:08 +00003074 printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
3075 printf("\t otherwise XML Catalogs starting from \n");
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003076 printf("\t %s are activated by default\n", XML_XML_DEFAULT_CATALOG);
Daniel Veillard05c13a22001-09-09 08:38:09 +00003077 printf("\t--nocatalogs: deactivate all catalogs\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003078#endif
3079 printf("\t--auto : generate a small doc on the fly\n");
3080#ifdef LIBXML_XINCLUDE_ENABLED
3081 printf("\t--xinclude : do XInclude processing\n");
Daniel Veillardc14c3892004-08-16 12:34:50 +00003082 printf("\t--noxincludenode : same but do not generate XInclude nodes\n");
Daniel Veillard54bd29b2008-08-26 07:26:55 +00003083 printf("\t--nofixup-base-uris : do not fixup xml:base uris\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003084#endif
Daniel Veillardcbaf3992001-12-31 16:16:02 +00003085 printf("\t--loaddtd : fetch external DTD\n");
Daniel Veillard48da9102001-08-07 01:10:10 +00003086 printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
Daniel Veillard81273902003-09-30 00:43:48 +00003087#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003088 printf("\t--stream : use the streaming interface to process very large files\n");
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003089 printf("\t--walker : create a reader and walk though the resulting doc\n");
Daniel Veillard81273902003-09-30 00:43:48 +00003090#endif /* LIBXML_READER_ENABLED */
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003091#ifdef LIBXML_PATTERN_ENABLED
3092 printf("\t--pattern pattern_value : test the pattern support\n");
3093#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003094 printf("\t--chkregister : verify the node registration code\n");
Daniel Veillardef4d3bc2003-02-07 12:38:22 +00003095#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard71531f32003-02-05 13:19:53 +00003096 printf("\t--relaxng schema : do RelaxNG validation against the schema\n");
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003097 printf("\t--schema schema : do validation against the WXS schema\n");
Daniel Veillard71531f32003-02-05 13:19:53 +00003098#endif
Daniel Veillarde70375c2005-07-30 21:09:12 +00003099#ifdef LIBXML_SCHEMATRON_ENABLED
3100 printf("\t--schematron schema : do validation against a schematron\n");
3101#endif
Daniel Veillard971771e2005-07-09 17:32:57 +00003102#ifdef LIBXML_SAX1_ENABLED
3103 printf("\t--sax1: use the old SAX1 interfaces for processing\n");
3104#endif
3105 printf("\t--sax: do not build a tree but work just at the SAX level\n");
Daniel Veillard7e5c3f42008-07-29 16:12:31 +00003106 printf("\t--oldxml10: use XML-1.0 parsing rules before the 5th edition\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003107#ifdef LIBXML_XPATH_ENABLED
Daniel Veillard113384f2013-03-27 11:43:41 +08003108 printf("\t--xpath expr: evaluate the XPath expression, imply --noout\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003109#endif
Daniel Veillard971771e2005-07-09 17:32:57 +00003110
Daniel Veillarda42f25f2002-01-25 14:15:40 +00003111 printf("\nLibxml project home page: http://xmlsoft.org/\n");
3112 printf("To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003113}
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003114
3115static void registerNode(xmlNodePtr node)
3116{
3117 node->_private = malloc(sizeof(long));
Daniel Veillarde71dce12013-07-11 15:41:22 +08003118 if (node->_private == NULL) {
3119 fprintf(stderr, "Out of memory in xmllint:registerNode()\n");
3120 exit(XMLLINT_ERR_MEM);
3121 }
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003122 *(long*)node->_private = (long) 0x81726354;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003123 nbregister++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003124}
3125
3126static void deregisterNode(xmlNodePtr node)
3127{
3128 assert(node->_private != NULL);
3129 assert(*(long*)node->_private == (long) 0x81726354);
3130 free(node->_private);
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003131 nbregister--;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003132}
3133
Daniel Veillard4a6845d2001-01-03 13:32:39 +00003134int
3135main(int argc, char **argv) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00003136 int i, acount;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003137 int files = 0;
Daniel Veillard845cce42002-01-09 11:51:37 +00003138 int version = 0;
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00003139 const char* indent;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003140
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003141 if (argc <= 1) {
3142 usage(argv[0]);
3143 return(1);
3144 }
Daniel Veillardbe803962000-06-28 23:40:59 +00003145 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003146 for (i = 1; i < argc ; i++) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003147 if (!strcmp(argv[i], "-"))
3148 break;
3149
3150 if (argv[i][0] != '-')
3151 continue;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003152 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
3153 debug++;
Daniel Veillard56ada1d2003-01-07 11:17:25 +00003154 else
3155#ifdef LIBXML_DEBUG_ENABLED
3156 if ((!strcmp(argv[i], "-shell")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003157 (!strcmp(argv[i], "--shell"))) {
3158 shell++;
3159 noout = 1;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003160 } else
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003161#endif
Daniel Veillard652327a2003-09-29 18:02:38 +00003162#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003163 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
3164 copy++;
Daniel Veillard652327a2003-09-29 18:02:38 +00003165 else
3166#endif /* LIBXML_TREE_ENABLED */
3167 if ((!strcmp(argv[i], "-recover")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003168 (!strcmp(argv[i], "--recover"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003169 recovery++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003170 options |= XML_PARSE_RECOVER;
Daniel Veillard8915c152008-08-26 13:05:34 +00003171 } else if ((!strcmp(argv[i], "-huge")) ||
3172 (!strcmp(argv[i], "--huge"))) {
3173 options |= XML_PARSE_HUGE;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003174 } else if ((!strcmp(argv[i], "-noent")) ||
3175 (!strcmp(argv[i], "--noent"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003176 noent++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003177 options |= XML_PARSE_NOENT;
Daniel Veillardc62efc82011-05-16 16:03:50 +08003178 } else if ((!strcmp(argv[i], "-noenc")) ||
3179 (!strcmp(argv[i], "--noenc"))) {
3180 noenc++;
3181 options |= XML_PARSE_IGNORE_ENC;
Daniel Veillarddca8cc72003-09-26 13:53:14 +00003182 } else if ((!strcmp(argv[i], "-nsclean")) ||
3183 (!strcmp(argv[i], "--nsclean"))) {
3184 options |= XML_PARSE_NSCLEAN;
3185 } else if ((!strcmp(argv[i], "-nocdata")) ||
3186 (!strcmp(argv[i], "--nocdata"))) {
3187 options |= XML_PARSE_NOCDATA;
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003188 } else if ((!strcmp(argv[i], "-nodict")) ||
3189 (!strcmp(argv[i], "--nodict"))) {
3190 options |= XML_PARSE_NODICT;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003191 } else if ((!strcmp(argv[i], "-version")) ||
Daniel Veillard845cce42002-01-09 11:51:37 +00003192 (!strcmp(argv[i], "--version"))) {
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00003193 showVersion(argv[0]);
Daniel Veillard845cce42002-01-09 11:51:37 +00003194 version = 1;
3195 } else if ((!strcmp(argv[i], "-noout")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003196 (!strcmp(argv[i], "--noout")))
3197 noout++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003198#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003199 else if ((!strcmp(argv[i], "-o")) ||
3200 (!strcmp(argv[i], "-output")) ||
3201 (!strcmp(argv[i], "--output"))) {
3202 i++;
Daniel Veillard6e4f1c02002-04-09 09:55:20 +00003203 output = argv[i];
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003204 }
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003205#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003206 else if ((!strcmp(argv[i], "-htmlout")) ||
3207 (!strcmp(argv[i], "--htmlout")))
3208 htmlout++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003209 else if ((!strcmp(argv[i], "-nowrap")) ||
3210 (!strcmp(argv[i], "--nowrap")))
3211 nowrap++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003212#ifdef LIBXML_HTML_ENABLED
3213 else if ((!strcmp(argv[i], "-html")) ||
3214 (!strcmp(argv[i], "--html"))) {
3215 html++;
3216 }
Daniel Veillard42fd4122003-11-04 08:47:48 +00003217 else if ((!strcmp(argv[i], "-xmlout")) ||
3218 (!strcmp(argv[i], "--xmlout"))) {
3219 xmlout++;
Daniel Veillardf1121c42010-07-26 14:02:42 +02003220 } else if ((!strcmp(argv[i], "-nodefdtd")) ||
3221 (!strcmp(argv[i], "--nodefdtd"))) {
3222 nodefdtd++;
3223 options |= HTML_PARSE_NODEFDTD;
Daniel Veillard42fd4122003-11-04 08:47:48 +00003224 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003225#endif /* LIBXML_HTML_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003226 else if ((!strcmp(argv[i], "-loaddtd")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003227 (!strcmp(argv[i], "--loaddtd"))) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003228 loaddtd++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003229 options |= XML_PARSE_DTDLOAD;
3230 } else if ((!strcmp(argv[i], "-dtdattr")) ||
Daniel Veillard48da9102001-08-07 01:10:10 +00003231 (!strcmp(argv[i], "--dtdattr"))) {
3232 loaddtd++;
3233 dtdattrs++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003234 options |= XML_PARSE_DTDATTR;
Daniel Veillard4432df22003-09-28 18:58:27 +00003235 }
3236#ifdef LIBXML_VALID_ENABLED
3237 else if ((!strcmp(argv[i], "-valid")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003238 (!strcmp(argv[i], "--valid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003239 valid++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003240 options |= XML_PARSE_DTDVALID;
3241 } else if ((!strcmp(argv[i], "-postvalid")) ||
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003242 (!strcmp(argv[i], "--postvalid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003243 postvalid++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003244 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003245 options |= XML_PARSE_DTDLOAD;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003246 } else if ((!strcmp(argv[i], "-dtdvalid")) ||
Daniel Veillardcd429612000-10-11 15:57:05 +00003247 (!strcmp(argv[i], "--dtdvalid"))) {
3248 i++;
3249 dtdvalid = argv[i];
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003250 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003251 options |= XML_PARSE_DTDLOAD;
Daniel Veillard66f68e72003-08-18 16:39:51 +00003252 } else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3253 (!strcmp(argv[i], "--dtdvalidfpi"))) {
3254 i++;
3255 dtdvalidfpi = argv[i];
3256 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003257 options |= XML_PARSE_DTDLOAD;
Daniel Veillardcd429612000-10-11 15:57:05 +00003258 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003259#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard29e43992001-12-13 22:21:58 +00003260 else if ((!strcmp(argv[i], "-dropdtd")) ||
3261 (!strcmp(argv[i], "--dropdtd")))
3262 dropdtd++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003263 else if ((!strcmp(argv[i], "-insert")) ||
3264 (!strcmp(argv[i], "--insert")))
3265 insert++;
Daniel Veillard48b2f892001-02-25 16:11:03 +00003266 else if ((!strcmp(argv[i], "-timing")) ||
3267 (!strcmp(argv[i], "--timing")))
3268 timing++;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00003269 else if ((!strcmp(argv[i], "-auto")) ||
3270 (!strcmp(argv[i], "--auto")))
3271 generate++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003272 else if ((!strcmp(argv[i], "-repeat")) ||
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00003273 (!strcmp(argv[i], "--repeat"))) {
3274 if (repeat)
3275 repeat *= 10;
3276 else
3277 repeat = 100;
Daniel Veillard73b013f2003-09-30 12:36:01 +00003278 }
3279#ifdef LIBXML_PUSH_ENABLED
3280 else if ((!strcmp(argv[i], "-push")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003281 (!strcmp(argv[i], "--push")))
3282 push++;
Daniel Veillard1abd2212012-10-25 15:37:50 +08003283 else if ((!strcmp(argv[i], "-pushsmall")) ||
3284 (!strcmp(argv[i], "--pushsmall"))) {
3285 push++;
3286 pushsize = 10;
3287 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00003288#endif /* LIBXML_PUSH_ENABLED */
Daniel Richard G5706b6d2012-08-06 11:32:54 +08003289#ifdef HAVE_MMAP
Daniel Veillard46e370e2000-07-21 20:32:03 +00003290 else if ((!strcmp(argv[i], "-memory")) ||
3291 (!strcmp(argv[i], "--memory")))
3292 memory++;
3293#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +00003294 else if ((!strcmp(argv[i], "-testIO")) ||
3295 (!strcmp(argv[i], "--testIO")))
3296 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003297#ifdef LIBXML_XINCLUDE_ENABLED
3298 else if ((!strcmp(argv[i], "-xinclude")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003299 (!strcmp(argv[i], "--xinclude"))) {
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003300 xinclude++;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003301 options |= XML_PARSE_XINCLUDE;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003302 }
Daniel Veillardc14c3892004-08-16 12:34:50 +00003303 else if ((!strcmp(argv[i], "-noxincludenode")) ||
3304 (!strcmp(argv[i], "--noxincludenode"))) {
3305 xinclude++;
3306 options |= XML_PARSE_XINCLUDE;
3307 options |= XML_PARSE_NOXINCNODE;
3308 }
Daniel Veillard54bd29b2008-08-26 07:26:55 +00003309 else if ((!strcmp(argv[i], "-nofixup-base-uris")) ||
3310 (!strcmp(argv[i], "--nofixup-base-uris"))) {
3311 xinclude++;
3312 options |= XML_PARSE_XINCLUDE;
3313 options |= XML_PARSE_NOBASEFIX;
3314 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003315#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003316#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003317#ifdef HAVE_ZLIB_H
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003318 else if ((!strcmp(argv[i], "-compress")) ||
3319 (!strcmp(argv[i], "--compress"))) {
3320 compress++;
3321 xmlSetCompressMode(9);
3322 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003323#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003324#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003325 else if ((!strcmp(argv[i], "-nowarning")) ||
3326 (!strcmp(argv[i], "--nowarning"))) {
3327 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003328 xmlPedanticParserDefault(0);
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003329 options |= XML_PARSE_NOWARNING;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003330 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003331 else if ((!strcmp(argv[i], "-pedantic")) ||
3332 (!strcmp(argv[i], "--pedantic"))) {
3333 xmlGetWarningsDefaultValue = 1;
3334 xmlPedanticParserDefault(1);
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003335 options |= XML_PARSE_PEDANTIC;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003336 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00003337#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003338 else if ((!strcmp(argv[i], "-debugent")) ||
3339 (!strcmp(argv[i], "--debugent"))) {
3340 debugent++;
3341 xmlParserDebugEntities = 1;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003342 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00003343#endif
Daniel Veillard25048d82004-08-14 22:37:54 +00003344#ifdef LIBXML_C14N_ENABLED
3345 else if ((!strcmp(argv[i], "-c14n")) ||
3346 (!strcmp(argv[i], "--c14n"))) {
3347 canonical++;
3348 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003349 }
Aleksey Sanin83868242009-07-09 10:26:22 +02003350 else if ((!strcmp(argv[i], "-c14n11")) ||
3351 (!strcmp(argv[i], "--c14n11"))) {
3352 canonical_11++;
3353 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003354 }
Aleksey Sanin2650df12005-06-06 17:16:50 +00003355 else if ((!strcmp(argv[i], "-exc-c14n")) ||
3356 (!strcmp(argv[i], "--exc-c14n"))) {
3357 exc_canonical++;
3358 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003359 }
Daniel Veillard25048d82004-08-14 22:37:54 +00003360#endif
Daniel Veillard81418e32001-05-22 15:08:55 +00003361#ifdef LIBXML_CATALOG_ENABLED
3362 else if ((!strcmp(argv[i], "-catalogs")) ||
3363 (!strcmp(argv[i], "--catalogs"))) {
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003364 catalogs++;
3365 } else if ((!strcmp(argv[i], "-nocatalogs")) ||
3366 (!strcmp(argv[i], "--nocatalogs"))) {
3367 nocatalogs++;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003368 }
Daniel Veillard81418e32001-05-22 15:08:55 +00003369#endif
Daniel Veillardbe803962000-06-28 23:40:59 +00003370 else if ((!strcmp(argv[i], "-encode")) ||
3371 (!strcmp(argv[i], "--encode"))) {
3372 i++;
3373 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003374 /*
3375 * OK it's for testing purposes
3376 */
3377 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +00003378 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003379 else if ((!strcmp(argv[i], "-noblanks")) ||
3380 (!strcmp(argv[i], "--noblanks"))) {
Daniel Veillardf933c892012-09-07 19:32:12 +08003381 noblanks++;
3382 xmlKeepBlanksDefault(0);
3383 options |= XML_PARSE_NOBLANKS;
Daniel Veillard90493a92001-08-14 14:12:47 +00003384 }
Daniel Veillard87076042004-05-03 22:54:49 +00003385 else if ((!strcmp(argv[i], "-maxmem")) ||
3386 (!strcmp(argv[i], "--maxmem"))) {
3387 i++;
3388 if (sscanf(argv[i], "%d", &maxmem) == 1) {
3389 xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc,
3390 myStrdupFunc);
3391 } else {
3392 maxmem = 0;
3393 }
3394 }
Daniel Veillard90493a92001-08-14 14:12:47 +00003395 else if ((!strcmp(argv[i], "-format")) ||
3396 (!strcmp(argv[i], "--format"))) {
3397 noblanks++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003398#ifdef LIBXML_OUTPUT_ENABLED
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01003399 format = 1;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003400#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard90493a92001-08-14 14:12:47 +00003401 xmlKeepBlanksDefault(0);
Daniel Veillard7704fb12003-01-03 16:19:51 +00003402 }
Adam Spraggd2e62312010-11-03 15:33:40 +01003403 else if ((!strcmp(argv[i], "-pretty")) ||
3404 (!strcmp(argv[i], "--pretty"))) {
3405 i++;
3406#ifdef LIBXML_OUTPUT_ENABLED
Tim Galeckas2205ff42013-08-29 16:44:33 +08003407 if (argv[i] != NULL) {
3408 format = atoi(argv[i]);
3409 if (format == 1) {
3410 noblanks++;
3411 xmlKeepBlanksDefault(0);
3412 }
3413 }
Brandon Slack0c7109c2012-05-11 10:50:59 +08003414#endif /* LIBXML_OUTPUT_ENABLED */
Adam Spraggd2e62312010-11-03 15:33:40 +01003415 }
Daniel Veillard81273902003-09-30 00:43:48 +00003416#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003417 else if ((!strcmp(argv[i], "-stream")) ||
3418 (!strcmp(argv[i], "--stream"))) {
3419 stream++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003420 }
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003421 else if ((!strcmp(argv[i], "-walker")) ||
3422 (!strcmp(argv[i], "--walker"))) {
3423 walker++;
3424 noout++;
3425 }
Daniel Veillard81273902003-09-30 00:43:48 +00003426#endif /* LIBXML_READER_ENABLED */
3427#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +00003428 else if ((!strcmp(argv[i], "-sax1")) ||
3429 (!strcmp(argv[i], "--sax1"))) {
Daniel Veillard023d0ba2009-07-29 11:34:50 +02003430 sax1++;
3431 options |= XML_PARSE_SAX1;
Daniel Veillard07cb8222003-09-10 10:51:05 +00003432 }
Daniel Veillard81273902003-09-30 00:43:48 +00003433#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003434 else if ((!strcmp(argv[i], "-sax")) ||
3435 (!strcmp(argv[i], "--sax"))) {
Daniel Veillard023d0ba2009-07-29 11:34:50 +02003436 sax++;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003437 }
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003438 else if ((!strcmp(argv[i], "-chkregister")) ||
3439 (!strcmp(argv[i], "--chkregister"))) {
Daniel Veillard023d0ba2009-07-29 11:34:50 +02003440 chkregister++;
Daniel Veillard71531f32003-02-05 13:19:53 +00003441#ifdef LIBXML_SCHEMAS_ENABLED
3442 } else if ((!strcmp(argv[i], "-relaxng")) ||
3443 (!strcmp(argv[i], "--relaxng"))) {
3444 i++;
3445 relaxng = argv[i];
3446 noent++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003447 options |= XML_PARSE_NOENT;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003448 } else if ((!strcmp(argv[i], "-schema")) ||
3449 (!strcmp(argv[i], "--schema"))) {
3450 i++;
3451 schema = argv[i];
3452 noent++;
Daniel Veillard71531f32003-02-05 13:19:53 +00003453#endif
Daniel Veillardd4501d72005-07-24 14:27:16 +00003454#ifdef LIBXML_SCHEMATRON_ENABLED
3455 } else if ((!strcmp(argv[i], "-schematron")) ||
3456 (!strcmp(argv[i], "--schematron"))) {
3457 i++;
3458 schematron = argv[i];
3459 noent++;
3460#endif
Daniel Veillarde8b09e42003-05-13 22:14:13 +00003461 } else if ((!strcmp(argv[i], "-nonet")) ||
3462 (!strcmp(argv[i], "--nonet"))) {
Daniel Veillard61b93382003-11-03 14:28:31 +00003463 options |= XML_PARSE_NONET;
Daniel Veillard968d6432006-04-25 16:17:53 +00003464 xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
Doran Moppert23040782017-04-07 16:45:56 +02003465 } else if ((!strcmp(argv[i], "-noxxe")) ||
3466 (!strcmp(argv[i], "--noxxe"))) {
3467 options |= XML_PARSE_NOXXE;
3468 xmlSetExternalEntityLoader(xmlNoXxeExternalEntityLoader);
Daniel Veillard8874b942005-08-25 13:19:21 +00003469 } else if ((!strcmp(argv[i], "-nocompact")) ||
3470 (!strcmp(argv[i], "--nocompact"))) {
3471 options &= ~XML_PARSE_COMPACT;
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003472 } else if ((!strcmp(argv[i], "-load-trace")) ||
3473 (!strcmp(argv[i], "--load-trace"))) {
3474 load_trace++;
3475 } else if ((!strcmp(argv[i], "-path")) ||
3476 (!strcmp(argv[i], "--path"))) {
3477 i++;
3478 parsePath(BAD_CAST argv[i]);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003479#ifdef LIBXML_PATTERN_ENABLED
3480 } else if ((!strcmp(argv[i], "-pattern")) ||
3481 (!strcmp(argv[i], "--pattern"))) {
3482 i++;
3483 pattern = argv[i];
3484#endif
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003485#ifdef LIBXML_XPATH_ENABLED
3486 } else if ((!strcmp(argv[i], "-xpath")) ||
3487 (!strcmp(argv[i], "--xpath"))) {
3488 i++;
3489 noout++;
3490 xpathquery = argv[i];
3491#endif
Daniel Veillard7e5c3f42008-07-29 16:12:31 +00003492 } else if ((!strcmp(argv[i], "-oldxml10")) ||
3493 (!strcmp(argv[i], "--oldxml10"))) {
3494 oldxml10++;
3495 options |= XML_PARSE_OLD10;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003496 } else {
3497 fprintf(stderr, "Unknown option %s\n", argv[i]);
3498 usage(argv[0]);
3499 return(1);
3500 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003501 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003502
3503#ifdef LIBXML_CATALOG_ENABLED
3504 if (nocatalogs == 0) {
3505 if (catalogs) {
3506 const char *catal;
3507
3508 catal = getenv("SGML_CATALOG_FILES");
Daniel Veillard6c5f9d12001-08-25 13:33:14 +00003509 if (catal != NULL) {
3510 xmlLoadCatalogs(catal);
3511 } else {
3512 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
3513 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003514 }
3515 }
3516#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003517
Daniel Veillard81273902003-09-30 00:43:48 +00003518#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +00003519 if (sax1)
3520 xmlSAXDefaultVersion(1);
3521 else
3522 xmlSAXDefaultVersion(2);
Daniel Veillard81273902003-09-30 00:43:48 +00003523#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillard07cb8222003-09-10 10:51:05 +00003524
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003525 if (chkregister) {
3526 xmlRegisterNodeDefault(registerNode);
3527 xmlDeregisterNodeDefault(deregisterNode);
3528 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02003529
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00003530 indent = getenv("XMLLINT_INDENT");
3531 if(indent != NULL) {
3532 xmlTreeIndentString = indent;
3533 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02003534
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003535
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003536 defaultEntityLoader = xmlGetExternalEntityLoader();
3537 xmlSetExternalEntityLoader(xmllintExternalEntityLoader);
3538
Daniel Veillardd9bad132001-07-23 19:39:43 +00003539 xmlLineNumbersDefault(1);
Daniel Veillard48da9102001-08-07 01:10:10 +00003540 if (loaddtd != 0)
3541 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
3542 if (dtdattrs)
3543 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003544 if (noent != 0) xmlSubstituteEntitiesDefault(1);
Daniel Veillard4432df22003-09-28 18:58:27 +00003545#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003546 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
Daniel Veillard4432df22003-09-28 18:58:27 +00003547#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003548 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003549 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003550 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003551 xmlGenericError(xmlGenericErrorContext,
3552 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
3553 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003554 "<html><head><title>%s output</title></head>\n",
3555 argv[0]);
Daniel Veillardf1edb102009-08-10 14:43:18 +02003556 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003557 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
3558 argv[0]);
3559 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003560
Daniel Veillardd4501d72005-07-24 14:27:16 +00003561#ifdef LIBXML_SCHEMATRON_ENABLED
3562 if ((schematron != NULL) && (sax == 0)
3563#ifdef LIBXML_READER_ENABLED
3564 && (stream == 0)
3565#endif /* LIBXML_READER_ENABLED */
3566 ) {
3567 xmlSchematronParserCtxtPtr ctxt;
3568
3569 /* forces loading the DTDs */
Daniel Veillardf1edb102009-08-10 14:43:18 +02003570 xmlLoadExtDtdDefaultValue |= 1;
Daniel Veillardd4501d72005-07-24 14:27:16 +00003571 options |= XML_PARSE_DTDLOAD;
3572 if (timing) {
3573 startTimer();
3574 }
3575 ctxt = xmlSchematronNewParserCtxt(schematron);
3576#if 0
3577 xmlSchematronSetParserErrors(ctxt,
3578 (xmlSchematronValidityErrorFunc) fprintf,
3579 (xmlSchematronValidityWarningFunc) fprintf,
3580 stderr);
3581#endif
3582 wxschematron = xmlSchematronParse(ctxt);
3583 if (wxschematron == NULL) {
3584 xmlGenericError(xmlGenericErrorContext,
3585 "Schematron schema %s failed to compile\n", schematron);
3586 progresult = XMLLINT_ERR_SCHEMACOMP;
3587 schematron = NULL;
3588 }
3589 xmlSchematronFreeParserCtxt(ctxt);
3590 if (timing) {
3591 endTimer("Compiling the schemas");
3592 }
3593 }
3594#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00003595#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003596 if ((relaxng != NULL) && (sax == 0)
Daniel Veillard81273902003-09-30 00:43:48 +00003597#ifdef LIBXML_READER_ENABLED
3598 && (stream == 0)
3599#endif /* LIBXML_READER_ENABLED */
3600 ) {
Daniel Veillard71531f32003-02-05 13:19:53 +00003601 xmlRelaxNGParserCtxtPtr ctxt;
3602
Daniel Veillardce192eb2003-04-16 15:58:05 +00003603 /* forces loading the DTDs */
Daniel Veillardf1edb102009-08-10 14:43:18 +02003604 xmlLoadExtDtdDefaultValue |= 1;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003605 options |= XML_PARSE_DTDLOAD;
Daniel Veillard42f12e92003-03-07 18:32:59 +00003606 if (timing) {
3607 startTimer();
3608 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003609 ctxt = xmlRelaxNGNewParserCtxt(relaxng);
3610 xmlRelaxNGSetParserErrors(ctxt,
3611 (xmlRelaxNGValidityErrorFunc) fprintf,
3612 (xmlRelaxNGValidityWarningFunc) fprintf,
3613 stderr);
3614 relaxngschemas = xmlRelaxNGParse(ctxt);
Daniel Veillardce192eb2003-04-16 15:58:05 +00003615 if (relaxngschemas == NULL) {
3616 xmlGenericError(xmlGenericErrorContext,
3617 "Relax-NG schema %s failed to compile\n", relaxng);
William M. Brack8304d872004-06-08 13:29:32 +00003618 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillardce192eb2003-04-16 15:58:05 +00003619 relaxng = NULL;
3620 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003621 xmlRelaxNGFreeParserCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00003622 if (timing) {
3623 endTimer("Compiling the schemas");
3624 }
Daniel Veillardebe25d42004-03-25 09:35:49 +00003625 } else if ((schema != NULL)
3626#ifdef LIBXML_READER_ENABLED
Daniel Veillardf10ae122005-07-10 19:03:16 +00003627 && (stream == 0)
Daniel Veillardebe25d42004-03-25 09:35:49 +00003628#endif
3629 ) {
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003630 xmlSchemaParserCtxtPtr ctxt;
3631
3632 if (timing) {
3633 startTimer();
3634 }
3635 ctxt = xmlSchemaNewParserCtxt(schema);
3636 xmlSchemaSetParserErrors(ctxt,
3637 (xmlSchemaValidityErrorFunc) fprintf,
3638 (xmlSchemaValidityWarningFunc) fprintf,
3639 stderr);
3640 wxschemas = xmlSchemaParse(ctxt);
3641 if (wxschemas == NULL) {
3642 xmlGenericError(xmlGenericErrorContext,
3643 "WXS schema %s failed to compile\n", schema);
William M. Brack8304d872004-06-08 13:29:32 +00003644 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003645 schema = NULL;
3646 }
3647 xmlSchemaFreeParserCtxt(ctxt);
3648 if (timing) {
3649 endTimer("Compiling the schemas");
3650 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003651 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003652#endif /* LIBXML_SCHEMAS_ENABLED */
3653#ifdef LIBXML_PATTERN_ENABLED
Daniel Veillard39e5c892005-07-03 22:48:50 +00003654 if ((pattern != NULL)
Daniel Veillardc9352532005-07-04 14:25:34 +00003655#ifdef LIBXML_READER_ENABLED
Daniel Veillard39e5c892005-07-03 22:48:50 +00003656 && (walker == 0)
3657#endif
3658 ) {
Daniel Veillardffa7b7e2003-12-05 16:10:21 +00003659 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003660 if (patternc == NULL) {
3661 xmlGenericError(xmlGenericErrorContext,
3662 "Pattern %s failed to compile\n", pattern);
William M. Brack8304d872004-06-08 13:29:32 +00003663 progresult = XMLLINT_ERR_SCHEMAPAT;
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003664 pattern = NULL;
3665 }
3666 }
3667#endif /* LIBXML_PATTERN_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003668 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +00003669 if ((!strcmp(argv[i], "-encode")) ||
3670 (!strcmp(argv[i], "--encode"))) {
3671 i++;
3672 continue;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003673 } else if ((!strcmp(argv[i], "-o")) ||
3674 (!strcmp(argv[i], "-output")) ||
3675 (!strcmp(argv[i], "--output"))) {
3676 i++;
3677 continue;
Daniel Veillardbe803962000-06-28 23:40:59 +00003678 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003679#ifdef LIBXML_VALID_ENABLED
Daniel Veillardcd429612000-10-11 15:57:05 +00003680 if ((!strcmp(argv[i], "-dtdvalid")) ||
3681 (!strcmp(argv[i], "--dtdvalid"))) {
3682 i++;
3683 continue;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003684 }
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003685 if ((!strcmp(argv[i], "-path")) ||
3686 (!strcmp(argv[i], "--path"))) {
3687 i++;
3688 continue;
Daniel Veillardcd429612000-10-11 15:57:05 +00003689 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00003690 if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3691 (!strcmp(argv[i], "--dtdvalidfpi"))) {
3692 i++;
3693 continue;
3694 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003695#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard71531f32003-02-05 13:19:53 +00003696 if ((!strcmp(argv[i], "-relaxng")) ||
3697 (!strcmp(argv[i], "--relaxng"))) {
3698 i++;
3699 continue;
3700 }
Daniel Veillard87076042004-05-03 22:54:49 +00003701 if ((!strcmp(argv[i], "-maxmem")) ||
3702 (!strcmp(argv[i], "--maxmem"))) {
3703 i++;
3704 continue;
3705 }
Adam Spraggd2e62312010-11-03 15:33:40 +01003706 if ((!strcmp(argv[i], "-pretty")) ||
3707 (!strcmp(argv[i], "--pretty"))) {
3708 i++;
3709 continue;
3710 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003711 if ((!strcmp(argv[i], "-schema")) ||
3712 (!strcmp(argv[i], "--schema"))) {
3713 i++;
3714 continue;
3715 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00003716 if ((!strcmp(argv[i], "-schematron")) ||
3717 (!strcmp(argv[i], "--schematron"))) {
3718 i++;
3719 continue;
3720 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003721#ifdef LIBXML_PATTERN_ENABLED
3722 if ((!strcmp(argv[i], "-pattern")) ||
3723 (!strcmp(argv[i], "--pattern"))) {
3724 i++;
3725 continue;
3726 }
3727#endif
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003728#ifdef LIBXML_XPATH_ENABLED
3729 if ((!strcmp(argv[i], "-xpath")) ||
3730 (!strcmp(argv[i], "--xpath"))) {
3731 i++;
3732 continue;
3733 }
3734#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00003735 if ((timing) && (repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00003736 startTimer();
Daniel Veillardcbaf3992001-12-31 16:16:02 +00003737 /* Remember file names. "-" means stdin. <sven@zen.org> */
Daniel Veillard4a6845d2001-01-03 13:32:39 +00003738 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003739 if (repeat) {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003740 xmlParserCtxtPtr ctxt = NULL;
3741
3742 for (acount = 0;acount < repeat;acount++) {
Daniel Veillard81273902003-09-30 00:43:48 +00003743#ifdef LIBXML_READER_ENABLED
Daniel Veillard198c1bf2003-10-20 17:07:41 +00003744 if (stream != 0) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00003745 streamFile(argv[i]);
Daniel Veillard198c1bf2003-10-20 17:07:41 +00003746 } else {
Daniel Veillard81273902003-09-30 00:43:48 +00003747#endif /* LIBXML_READER_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003748 if (sax) {
3749 testSAX(argv[i]);
3750 } else {
3751 if (ctxt == NULL)
3752 ctxt = xmlNewParserCtxt();
3753 parseAndPrintFile(argv[i], ctxt);
3754 }
Daniel Veillard81273902003-09-30 00:43:48 +00003755#ifdef LIBXML_READER_ENABLED
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003756 }
Daniel Veillard81273902003-09-30 00:43:48 +00003757#endif /* LIBXML_READER_ENABLED */
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003758 }
3759 if (ctxt != NULL)
3760 xmlFreeParserCtxt(ctxt);
Daniel Veillard7704fb12003-01-03 16:19:51 +00003761 } else {
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003762 nbregister = 0;
3763
Daniel Veillard81273902003-09-30 00:43:48 +00003764#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003765 if (stream != 0)
3766 streamFile(argv[i]);
3767 else
Daniel Veillard81273902003-09-30 00:43:48 +00003768#endif /* LIBXML_READER_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003769 if (sax) {
3770 testSAX(argv[i]);
3771 } else {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003772 parseAndPrintFile(argv[i], NULL);
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003773 }
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003774
3775 if ((chkregister) && (nbregister != 0)) {
3776 fprintf(stderr, "Registration count off: %d\n", nbregister);
William M. Brack8304d872004-06-08 13:29:32 +00003777 progresult = XMLLINT_ERR_RDREGIS;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003778 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00003779 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003780 files ++;
Daniel Veillarda7866932001-12-04 13:14:44 +00003781 if ((timing) && (repeat)) {
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00003782 endTimer("%d iterations", repeat);
Daniel Veillarda7866932001-12-04 13:14:44 +00003783 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00003784 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003785 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02003786 if (generate)
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003787 parseAndPrintFile(NULL, NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003788 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003789 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003790 }
Daniel Veillard845cce42002-01-09 11:51:37 +00003791 if ((files == 0) && (!generate) && (version == 0)) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003792 usage(argv[0]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003793 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00003794#ifdef LIBXML_SCHEMATRON_ENABLED
3795 if (wxschematron != NULL)
3796 xmlSchematronFree(wxschematron);
3797#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00003798#ifdef LIBXML_SCHEMAS_ENABLED
3799 if (relaxngschemas != NULL)
3800 xmlRelaxNGFree(relaxngschemas);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003801 if (wxschemas != NULL)
3802 xmlSchemaFree(wxschemas);
Daniel Veillard71531f32003-02-05 13:19:53 +00003803 xmlRelaxNGCleanupTypes();
3804#endif
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003805#ifdef LIBXML_PATTERN_ENABLED
3806 if (patternc != NULL)
3807 xmlFreePattern(patternc);
3808#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003809 xmlCleanupParser();
3810 xmlMemoryDump();
3811
Daniel Veillardf7cd4812001-02-23 18:44:52 +00003812 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003813}
Daniel Veillard88a172f2000-08-04 18:23:10 +00003814