blob: b297ded12f57bf0ab578f85ed03718e67da9b433 [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 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000452static void XMLCDECL
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}
Daniel Veillardffa3c742005-07-21 13:24:09 +0000488static void XMLCDECL
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}
Daniel Veillardffa3c742005-07-21 13:24:09 +0000517static void XMLCDECL
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 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000637static void XMLCDECL
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 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000674static void XMLCDECL
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 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000712static void XMLCDECL
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 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000749static void XMLCDECL
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);
812 if (!fgets(line_read, 500, stdin))
813 return(NULL);
814 line_read[500] = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000815 len = strlen(line_read);
816 ret = (char *) malloc(len + 1);
817 if (ret != NULL) {
818 memcpy (ret, line_read, len + 1);
819 }
820 return(ret);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000821#endif
822}
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000823#endif /* LIBXML_XPATH_ENABLED */
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000824#endif /* LIBXML_DEBUG_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000825
826/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +0200827 * *
828 * I/O Interfaces *
829 * *
Daniel Veillard5e873c42000-04-12 13:27:38 +0000830 ************************************************************************/
831
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000832static int myRead(FILE *f, char * buf, int len) {
833 return(fread(buf, 1, len, f));
Daniel Veillard5e873c42000-04-12 13:27:38 +0000834}
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000835static void myClose(FILE *f) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000836 if (f != stdin) {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000837 fclose(f);
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000838 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000839}
840
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000841/************************************************************************
842 * *
Daniel Veillardf1edb102009-08-10 14:43:18 +0200843 * SAX based tests *
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000844 * *
845 ************************************************************************/
846
847/*
848 * empty SAX block
849 */
Daniel Veillard24505b02005-07-28 23:49:35 +0000850static xmlSAXHandler emptySAXHandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000851 NULL, /* internalSubset */
852 NULL, /* isStandalone */
853 NULL, /* hasInternalSubset */
854 NULL, /* hasExternalSubset */
855 NULL, /* resolveEntity */
856 NULL, /* getEntity */
857 NULL, /* entityDecl */
858 NULL, /* notationDecl */
859 NULL, /* attributeDecl */
860 NULL, /* elementDecl */
861 NULL, /* unparsedEntityDecl */
862 NULL, /* setDocumentLocator */
863 NULL, /* startDocument */
864 NULL, /* endDocument */
865 NULL, /* startElement */
866 NULL, /* endElement */
867 NULL, /* reference */
868 NULL, /* characters */
869 NULL, /* ignorableWhitespace */
870 NULL, /* processingInstruction */
871 NULL, /* comment */
872 NULL, /* xmlParserWarning */
873 NULL, /* xmlParserError */
874 NULL, /* xmlParserError */
875 NULL, /* getParameterEntity */
876 NULL, /* cdataBlock; */
877 NULL, /* externalSubset; */
Daniel Veillard971771e2005-07-09 17:32:57 +0000878 XML_SAX2_MAGIC,
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000879 NULL,
880 NULL, /* startElementNs */
881 NULL, /* endElementNs */
882 NULL /* xmlStructuredErrorFunc */
883};
884
Daniel Veillard24505b02005-07-28 23:49:35 +0000885static xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000886extern xmlSAXHandlerPtr debugSAXHandler;
887static int callbacks;
888
889/**
890 * isStandaloneDebug:
891 * @ctxt: An XML parser context
892 *
893 * Is this document tagged standalone ?
894 *
895 * Returns 1 if true
896 */
897static int
898isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
899{
900 callbacks++;
901 if (noout)
902 return(0);
903 fprintf(stdout, "SAX.isStandalone()\n");
904 return(0);
905}
906
907/**
908 * hasInternalSubsetDebug:
909 * @ctxt: An XML parser context
910 *
911 * Does this document has an internal subset
912 *
913 * Returns 1 if true
914 */
915static int
916hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
917{
918 callbacks++;
919 if (noout)
920 return(0);
921 fprintf(stdout, "SAX.hasInternalSubset()\n");
922 return(0);
923}
924
925/**
926 * hasExternalSubsetDebug:
927 * @ctxt: An XML parser context
928 *
929 * Does this document has an external subset
930 *
931 * Returns 1 if true
932 */
933static int
934hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
935{
936 callbacks++;
937 if (noout)
938 return(0);
939 fprintf(stdout, "SAX.hasExternalSubset()\n");
940 return(0);
941}
942
943/**
944 * internalSubsetDebug:
945 * @ctxt: An XML parser context
946 *
947 * Does this document has an internal subset
948 */
949static void
950internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
951 const xmlChar *ExternalID, const xmlChar *SystemID)
952{
953 callbacks++;
954 if (noout)
955 return;
956 fprintf(stdout, "SAX.internalSubset(%s,", name);
957 if (ExternalID == NULL)
958 fprintf(stdout, " ,");
959 else
960 fprintf(stdout, " %s,", ExternalID);
961 if (SystemID == NULL)
962 fprintf(stdout, " )\n");
963 else
964 fprintf(stdout, " %s)\n", SystemID);
965}
966
967/**
968 * externalSubsetDebug:
969 * @ctxt: An XML parser context
970 *
971 * Does this document has an external subset
972 */
973static void
974externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
975 const xmlChar *ExternalID, const xmlChar *SystemID)
976{
977 callbacks++;
978 if (noout)
979 return;
980 fprintf(stdout, "SAX.externalSubset(%s,", name);
981 if (ExternalID == NULL)
982 fprintf(stdout, " ,");
983 else
984 fprintf(stdout, " %s,", ExternalID);
985 if (SystemID == NULL)
986 fprintf(stdout, " )\n");
987 else
988 fprintf(stdout, " %s)\n", SystemID);
989}
990
991/**
992 * resolveEntityDebug:
993 * @ctxt: An XML parser context
994 * @publicId: The public ID of the entity
995 * @systemId: The system ID of the entity
996 *
997 * Special entity resolver, better left to the parser, it has
998 * more context than the application layer.
999 * The default behaviour is to NOT resolve the entities, in that case
1000 * the ENTITY_REF nodes are built in the structure (and the parameter
1001 * values).
1002 *
1003 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
1004 */
1005static xmlParserInputPtr
1006resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
1007{
1008 callbacks++;
1009 if (noout)
1010 return(NULL);
1011 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1012
Daniel Veillardf1edb102009-08-10 14:43:18 +02001013
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001014 fprintf(stdout, "SAX.resolveEntity(");
1015 if (publicId != NULL)
1016 fprintf(stdout, "%s", (char *)publicId);
1017 else
1018 fprintf(stdout, " ");
1019 if (systemId != NULL)
1020 fprintf(stdout, ", %s)\n", (char *)systemId);
1021 else
1022 fprintf(stdout, ", )\n");
1023 return(NULL);
1024}
1025
1026/**
1027 * getEntityDebug:
1028 * @ctxt: An XML parser context
1029 * @name: The entity name
1030 *
1031 * Get an entity by name
1032 *
1033 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
1034 */
1035static xmlEntityPtr
1036getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1037{
1038 callbacks++;
1039 if (noout)
1040 return(NULL);
1041 fprintf(stdout, "SAX.getEntity(%s)\n", name);
1042 return(NULL);
1043}
1044
1045/**
1046 * getParameterEntityDebug:
1047 * @ctxt: An XML parser context
1048 * @name: The entity name
1049 *
1050 * Get a parameter entity by name
1051 *
1052 * Returns the xmlParserInputPtr
1053 */
1054static xmlEntityPtr
1055getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1056{
1057 callbacks++;
1058 if (noout)
1059 return(NULL);
1060 fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
1061 return(NULL);
1062}
1063
1064
1065/**
1066 * entityDeclDebug:
1067 * @ctxt: An XML parser context
Daniel Veillardf1edb102009-08-10 14:43:18 +02001068 * @name: the entity name
1069 * @type: the entity type
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001070 * @publicId: The public ID of the entity
1071 * @systemId: The system ID of the entity
1072 * @content: the entity value (without processing).
1073 *
1074 * An entity definition has been parsed
1075 */
1076static void
1077entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
1078 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
1079{
1080const xmlChar *nullstr = BAD_CAST "(null)";
1081 /* not all libraries handle printing null pointers nicely */
1082 if (publicId == NULL)
1083 publicId = nullstr;
1084 if (systemId == NULL)
1085 systemId = nullstr;
1086 if (content == NULL)
1087 content = (xmlChar *)nullstr;
1088 callbacks++;
1089 if (noout)
1090 return;
1091 fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
1092 name, type, publicId, systemId, content);
1093}
1094
1095/**
1096 * attributeDeclDebug:
1097 * @ctxt: An XML parser context
Daniel Veillardf1edb102009-08-10 14:43:18 +02001098 * @name: the attribute name
1099 * @type: the attribute type
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001100 *
1101 * An attribute definition has been parsed
1102 */
1103static void
1104attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar * elem,
1105 const xmlChar * name, int type, int def,
1106 const xmlChar * defaultValue, xmlEnumerationPtr tree)
1107{
1108 callbacks++;
1109 if (noout)
1110 return;
1111 if (defaultValue == NULL)
1112 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
1113 elem, name, type, def);
1114 else
1115 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
1116 elem, name, type, def, defaultValue);
1117 xmlFreeEnumeration(tree);
1118}
1119
1120/**
1121 * elementDeclDebug:
1122 * @ctxt: An XML parser context
Daniel Veillardf1edb102009-08-10 14:43:18 +02001123 * @name: the element name
1124 * @type: the element type
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001125 * @content: the element value (without processing).
1126 *
1127 * An element definition has been parsed
1128 */
1129static void
1130elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
1131 xmlElementContentPtr content ATTRIBUTE_UNUSED)
1132{
1133 callbacks++;
1134 if (noout)
1135 return;
1136 fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
1137 name, type);
1138}
1139
1140/**
1141 * notationDeclDebug:
1142 * @ctxt: An XML parser context
1143 * @name: The name of the notation
1144 * @publicId: The public ID of the entity
1145 * @systemId: The system ID of the entity
1146 *
1147 * What to do when a notation declaration has been parsed.
1148 */
1149static void
1150notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
1151 const xmlChar *publicId, const xmlChar *systemId)
1152{
1153 callbacks++;
1154 if (noout)
1155 return;
1156 fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
1157 (char *) name, (char *) publicId, (char *) systemId);
1158}
1159
1160/**
1161 * unparsedEntityDeclDebug:
1162 * @ctxt: An XML parser context
1163 * @name: The name of the entity
1164 * @publicId: The public ID of the entity
1165 * @systemId: The system ID of the entity
1166 * @notationName: the name of the notation
1167 *
1168 * What to do when an unparsed entity declaration is parsed
1169 */
1170static void
1171unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
1172 const xmlChar *publicId, const xmlChar *systemId,
1173 const xmlChar *notationName)
1174{
1175const xmlChar *nullstr = BAD_CAST "(null)";
1176
1177 if (publicId == NULL)
1178 publicId = nullstr;
1179 if (systemId == NULL)
1180 systemId = nullstr;
1181 if (notationName == NULL)
1182 notationName = nullstr;
1183 callbacks++;
1184 if (noout)
1185 return;
1186 fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
1187 (char *) name, (char *) publicId, (char *) systemId,
1188 (char *) notationName);
1189}
1190
1191/**
1192 * setDocumentLocatorDebug:
1193 * @ctxt: An XML parser context
1194 * @loc: A SAX Locator
1195 *
1196 * Receive the document locator at startup, actually xmlDefaultSAXLocator
1197 * Everything is available on the context, so this is useless in our case.
1198 */
1199static void
1200setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
1201{
1202 callbacks++;
1203 if (noout)
1204 return;
1205 fprintf(stdout, "SAX.setDocumentLocator()\n");
1206}
1207
1208/**
1209 * startDocumentDebug:
1210 * @ctxt: An XML parser context
1211 *
1212 * called when the document start being processed.
1213 */
1214static void
1215startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
1216{
1217 callbacks++;
1218 if (noout)
1219 return;
1220 fprintf(stdout, "SAX.startDocument()\n");
1221}
1222
1223/**
1224 * endDocumentDebug:
1225 * @ctxt: An XML parser context
1226 *
1227 * called when the document end has been detected.
1228 */
1229static void
1230endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
1231{
1232 callbacks++;
1233 if (noout)
1234 return;
1235 fprintf(stdout, "SAX.endDocument()\n");
1236}
1237
1238/**
1239 * startElementDebug:
1240 * @ctxt: An XML parser context
1241 * @name: The element name
1242 *
1243 * called when an opening tag has been processed.
1244 */
1245static void
1246startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
1247{
1248 int i;
1249
1250 callbacks++;
1251 if (noout)
1252 return;
1253 fprintf(stdout, "SAX.startElement(%s", (char *) name);
1254 if (atts != NULL) {
1255 for (i = 0;(atts[i] != NULL);i++) {
1256 fprintf(stdout, ", %s='", atts[i++]);
1257 if (atts[i] != NULL)
1258 fprintf(stdout, "%s'", atts[i]);
1259 }
1260 }
1261 fprintf(stdout, ")\n");
1262}
1263
1264/**
1265 * endElementDebug:
1266 * @ctxt: An XML parser context
1267 * @name: The element name
1268 *
1269 * called when the end of an element has been detected.
1270 */
1271static void
1272endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1273{
1274 callbacks++;
1275 if (noout)
1276 return;
1277 fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
1278}
1279
1280/**
1281 * charactersDebug:
1282 * @ctxt: An XML parser context
1283 * @ch: a xmlChar string
1284 * @len: the number of xmlChar
1285 *
1286 * receiving some chars from the parser.
1287 * Question: how much at a time ???
1288 */
1289static void
1290charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
1291{
1292 char out[40];
1293 int i;
1294
1295 callbacks++;
1296 if (noout)
1297 return;
1298 for (i = 0;(i<len) && (i < 30);i++)
1299 out[i] = ch[i];
1300 out[i] = 0;
1301
1302 fprintf(stdout, "SAX.characters(%s, %d)\n", out, len);
1303}
1304
1305/**
1306 * referenceDebug:
1307 * @ctxt: An XML parser context
1308 * @name: The entity name
1309 *
Daniel Veillardf1edb102009-08-10 14:43:18 +02001310 * called when an entity reference is detected.
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001311 */
1312static void
1313referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1314{
1315 callbacks++;
1316 if (noout)
1317 return;
1318 fprintf(stdout, "SAX.reference(%s)\n", name);
1319}
1320
1321/**
1322 * ignorableWhitespaceDebug:
1323 * @ctxt: An XML parser context
1324 * @ch: a xmlChar string
1325 * @start: the first char in the string
1326 * @len: the number of xmlChar
1327 *
1328 * receiving some ignorable whitespaces from the parser.
1329 * Question: how much at a time ???
1330 */
1331static void
1332ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
1333{
1334 char out[40];
1335 int i;
1336
1337 callbacks++;
1338 if (noout)
1339 return;
1340 for (i = 0;(i<len) && (i < 30);i++)
1341 out[i] = ch[i];
1342 out[i] = 0;
1343 fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", out, len);
1344}
1345
1346/**
1347 * processingInstructionDebug:
1348 * @ctxt: An XML parser context
1349 * @target: the target name
1350 * @data: the PI data's
1351 * @len: the number of xmlChar
1352 *
1353 * A processing instruction has been parsed.
1354 */
1355static void
1356processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
1357 const xmlChar *data)
1358{
1359 callbacks++;
1360 if (noout)
1361 return;
1362 if (data != NULL)
1363 fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
1364 (char *) target, (char *) data);
1365 else
1366 fprintf(stdout, "SAX.processingInstruction(%s, NULL)\n",
1367 (char *) target);
1368}
1369
1370/**
1371 * cdataBlockDebug:
1372 * @ctx: the user data (XML parser context)
1373 * @value: The pcdata content
1374 * @len: the block length
1375 *
1376 * called when a pcdata block has been parsed
1377 */
1378static void
1379cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
1380{
1381 callbacks++;
1382 if (noout)
1383 return;
1384 fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
1385 (char *) value, len);
1386}
1387
1388/**
1389 * commentDebug:
1390 * @ctxt: An XML parser context
1391 * @value: the comment content
1392 *
1393 * A comment has been parsed.
1394 */
1395static void
1396commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
1397{
1398 callbacks++;
1399 if (noout)
1400 return;
1401 fprintf(stdout, "SAX.comment(%s)\n", value);
1402}
1403
1404/**
1405 * warningDebug:
1406 * @ctxt: An XML parser context
1407 * @msg: the message to display/transmit
1408 * @...: extra parameters for the message display
1409 *
1410 * Display and format a warning messages, gives file, line, position and
1411 * extra parameters.
1412 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001413static void XMLCDECL
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001414warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1415{
1416 va_list args;
1417
1418 callbacks++;
1419 if (noout)
1420 return;
1421 va_start(args, msg);
1422 fprintf(stdout, "SAX.warning: ");
1423 vfprintf(stdout, msg, args);
1424 va_end(args);
1425}
1426
1427/**
1428 * errorDebug:
1429 * @ctxt: An XML parser context
1430 * @msg: the message to display/transmit
1431 * @...: extra parameters for the message display
1432 *
1433 * Display and format a error messages, gives file, line, position and
1434 * extra parameters.
1435 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001436static void XMLCDECL
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001437errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1438{
1439 va_list args;
1440
1441 callbacks++;
1442 if (noout)
1443 return;
1444 va_start(args, msg);
1445 fprintf(stdout, "SAX.error: ");
1446 vfprintf(stdout, msg, args);
1447 va_end(args);
1448}
1449
1450/**
1451 * fatalErrorDebug:
1452 * @ctxt: An XML parser context
1453 * @msg: the message to display/transmit
1454 * @...: extra parameters for the message display
1455 *
1456 * Display and format a fatalError messages, gives file, line, position and
1457 * extra parameters.
1458 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001459static void XMLCDECL
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001460fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1461{
1462 va_list args;
1463
1464 callbacks++;
1465 if (noout)
1466 return;
1467 va_start(args, msg);
1468 fprintf(stdout, "SAX.fatalError: ");
1469 vfprintf(stdout, msg, args);
1470 va_end(args);
1471}
1472
Daniel Veillard24505b02005-07-28 23:49:35 +00001473static xmlSAXHandler debugSAXHandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001474 internalSubsetDebug,
1475 isStandaloneDebug,
1476 hasInternalSubsetDebug,
1477 hasExternalSubsetDebug,
1478 resolveEntityDebug,
1479 getEntityDebug,
1480 entityDeclDebug,
1481 notationDeclDebug,
1482 attributeDeclDebug,
1483 elementDeclDebug,
1484 unparsedEntityDeclDebug,
1485 setDocumentLocatorDebug,
1486 startDocumentDebug,
1487 endDocumentDebug,
1488 startElementDebug,
1489 endElementDebug,
1490 referenceDebug,
1491 charactersDebug,
1492 ignorableWhitespaceDebug,
1493 processingInstructionDebug,
1494 commentDebug,
1495 warningDebug,
1496 errorDebug,
1497 fatalErrorDebug,
1498 getParameterEntityDebug,
1499 cdataBlockDebug,
1500 externalSubsetDebug,
1501 1,
1502 NULL,
1503 NULL,
1504 NULL,
1505 NULL
1506};
1507
1508xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
1509
1510/*
1511 * SAX2 specific callbacks
1512 */
1513/**
1514 * startElementNsDebug:
1515 * @ctxt: An XML parser context
1516 * @name: The element name
1517 *
1518 * called when an opening tag has been processed.
1519 */
1520static void
1521startElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
1522 const xmlChar *localname,
1523 const xmlChar *prefix,
1524 const xmlChar *URI,
1525 int nb_namespaces,
1526 const xmlChar **namespaces,
1527 int nb_attributes,
1528 int nb_defaulted,
1529 const xmlChar **attributes)
1530{
1531 int i;
1532
1533 callbacks++;
1534 if (noout)
1535 return;
1536 fprintf(stdout, "SAX.startElementNs(%s", (char *) localname);
1537 if (prefix == NULL)
1538 fprintf(stdout, ", NULL");
1539 else
1540 fprintf(stdout, ", %s", (char *) prefix);
1541 if (URI == NULL)
1542 fprintf(stdout, ", NULL");
1543 else
1544 fprintf(stdout, ", '%s'", (char *) URI);
1545 fprintf(stdout, ", %d", nb_namespaces);
Daniel Veillardf1edb102009-08-10 14:43:18 +02001546
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001547 if (namespaces != NULL) {
1548 for (i = 0;i < nb_namespaces * 2;i++) {
1549 fprintf(stdout, ", xmlns");
1550 if (namespaces[i] != NULL)
1551 fprintf(stdout, ":%s", namespaces[i]);
1552 i++;
1553 fprintf(stdout, "='%s'", namespaces[i]);
1554 }
1555 }
1556 fprintf(stdout, ", %d, %d", nb_attributes, nb_defaulted);
1557 if (attributes != NULL) {
1558 for (i = 0;i < nb_attributes * 5;i += 5) {
1559 if (attributes[i + 1] != NULL)
1560 fprintf(stdout, ", %s:%s='", attributes[i + 1], attributes[i]);
1561 else
1562 fprintf(stdout, ", %s='", attributes[i]);
1563 fprintf(stdout, "%.4s...', %d", attributes[i + 3],
1564 (int)(attributes[i + 4] - attributes[i + 3]));
1565 }
1566 }
1567 fprintf(stdout, ")\n");
1568}
1569
1570/**
1571 * endElementDebug:
1572 * @ctxt: An XML parser context
1573 * @name: The element name
1574 *
1575 * called when the end of an element has been detected.
1576 */
1577static void
1578endElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
1579 const xmlChar *localname,
1580 const xmlChar *prefix,
1581 const xmlChar *URI)
1582{
1583 callbacks++;
1584 if (noout)
1585 return;
1586 fprintf(stdout, "SAX.endElementNs(%s", (char *) localname);
1587 if (prefix == NULL)
1588 fprintf(stdout, ", NULL");
1589 else
1590 fprintf(stdout, ", %s", (char *) prefix);
1591 if (URI == NULL)
1592 fprintf(stdout, ", NULL)\n");
1593 else
1594 fprintf(stdout, ", '%s')\n", (char *) URI);
1595}
1596
Daniel Veillard24505b02005-07-28 23:49:35 +00001597static xmlSAXHandler debugSAX2HandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001598 internalSubsetDebug,
1599 isStandaloneDebug,
1600 hasInternalSubsetDebug,
1601 hasExternalSubsetDebug,
1602 resolveEntityDebug,
1603 getEntityDebug,
1604 entityDeclDebug,
1605 notationDeclDebug,
1606 attributeDeclDebug,
1607 elementDeclDebug,
1608 unparsedEntityDeclDebug,
1609 setDocumentLocatorDebug,
1610 startDocumentDebug,
1611 endDocumentDebug,
1612 NULL,
1613 NULL,
1614 referenceDebug,
1615 charactersDebug,
1616 ignorableWhitespaceDebug,
1617 processingInstructionDebug,
1618 commentDebug,
1619 warningDebug,
1620 errorDebug,
1621 fatalErrorDebug,
1622 getParameterEntityDebug,
1623 cdataBlockDebug,
1624 externalSubsetDebug,
1625 XML_SAX2_MAGIC,
1626 NULL,
1627 startElementNsDebug,
1628 endElementNsDebug,
1629 NULL
1630};
1631
Daniel Veillard24505b02005-07-28 23:49:35 +00001632static xmlSAXHandlerPtr debugSAX2Handler = &debugSAX2HandlerStruct;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001633
1634static void
1635testSAX(const char *filename) {
1636 xmlSAXHandlerPtr handler;
1637 const char *user_data = "user_data"; /* mostly for debugging */
1638 xmlParserInputBufferPtr buf = NULL;
1639 xmlParserInputPtr inputStream;
1640 xmlParserCtxtPtr ctxt = NULL;
1641 xmlSAXHandlerPtr old_sax = NULL;
1642
1643 callbacks = 0;
1644
1645 if (noout) {
1646 handler = emptySAXHandler;
Daniel Veillard78dfc9f2005-07-10 22:30:30 +00001647#ifdef LIBXML_SAX1_ENABLED
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001648 } else if (sax1) {
1649 handler = debugSAXHandler;
Daniel Veillard78dfc9f2005-07-10 22:30:30 +00001650#endif
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001651 } else {
1652 handler = debugSAX2Handler;
1653 }
1654
1655 /*
1656 * it's not the simplest code but the most generic in term of I/O
1657 */
1658 buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
1659 if (buf == NULL) {
1660 goto error;
1661 }
1662
1663#ifdef LIBXML_SCHEMAS_ENABLED
1664 if (wxschemas != NULL) {
1665 int ret;
1666 xmlSchemaValidCtxtPtr vctxt;
1667
1668 vctxt = xmlSchemaNewValidCtxt(wxschemas);
1669 xmlSchemaSetValidErrors(vctxt,
1670 (xmlSchemaValidityErrorFunc) fprintf,
1671 (xmlSchemaValidityWarningFunc) fprintf,
1672 stderr);
Daniel Veillard97fa5b32012-08-14 11:01:07 +08001673 xmlSchemaValidateSetFilename(vctxt, filename);
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001674
Daniel Veillard971771e2005-07-09 17:32:57 +00001675 ret = xmlSchemaValidateStream(vctxt, buf, 0, handler,
1676 (void *)user_data);
1677 if (repeat == 0) {
1678 if (ret == 0) {
1679 fprintf(stderr, "%s validates\n", filename);
1680 } else if (ret > 0) {
1681 fprintf(stderr, "%s fails to validate\n", filename);
1682 progresult = XMLLINT_ERR_VALID;
1683 } else {
1684 fprintf(stderr, "%s validation generated an internal error\n",
1685 filename);
1686 progresult = XMLLINT_ERR_VALID;
1687 }
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001688 }
1689 xmlSchemaFreeValidCtxt(vctxt);
1690 } else
1691#endif
1692 {
1693 /*
1694 * Create the parser context amd hook the input
1695 */
1696 ctxt = xmlNewParserCtxt();
1697 if (ctxt == NULL) {
1698 xmlFreeParserInputBuffer(buf);
1699 goto error;
1700 }
1701 old_sax = ctxt->sax;
1702 ctxt->sax = handler;
1703 ctxt->userData = (void *) user_data;
1704 inputStream = xmlNewIOInputStream(ctxt, buf, XML_CHAR_ENCODING_NONE);
1705 if (inputStream == NULL) {
1706 xmlFreeParserInputBuffer(buf);
1707 goto error;
1708 }
1709 inputPush(ctxt, inputStream);
Daniel Veillardf1edb102009-08-10 14:43:18 +02001710
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001711 /* do the parsing */
1712 xmlParseDocument(ctxt);
1713
1714 if (ctxt->myDoc != NULL) {
1715 fprintf(stderr, "SAX generated a doc !\n");
1716 xmlFreeDoc(ctxt->myDoc);
1717 ctxt->myDoc = NULL;
1718 }
1719 }
1720
1721error:
1722 if (ctxt != NULL) {
1723 ctxt->sax = old_sax;
1724 xmlFreeParserCtxt(ctxt);
1725 }
1726}
1727
Daniel Veillard5e873c42000-04-12 13:27:38 +00001728/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +02001729 * *
1730 * Stream Test processing *
1731 * *
Daniel Veillard7704fb12003-01-03 16:19:51 +00001732 ************************************************************************/
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001733#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00001734static void processNode(xmlTextReaderPtr reader) {
Daniel Veillard198c1bf2003-10-20 17:07:41 +00001735 const xmlChar *name, *value;
Daniel Veillard16ef8002005-01-31 00:27:50 +00001736 int type, empty;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001737
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001738 type = xmlTextReaderNodeType(reader);
Daniel Veillard16ef8002005-01-31 00:27:50 +00001739 empty = xmlTextReaderIsEmptyElement(reader);
Daniel Veillard99737f52003-03-22 14:55:50 +00001740
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001741 if (debug) {
1742 name = xmlTextReaderConstName(reader);
1743 if (name == NULL)
1744 name = BAD_CAST "--";
Daniel Veillard7704fb12003-01-03 16:19:51 +00001745
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001746 value = xmlTextReaderConstValue(reader);
1747
Daniel Veillardf1edb102009-08-10 14:43:18 +02001748
1749 printf("%d %d %s %d %d",
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001750 xmlTextReaderDepth(reader),
1751 type,
1752 name,
Daniel Veillard16ef8002005-01-31 00:27:50 +00001753 empty,
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001754 xmlTextReaderHasValue(reader));
1755 if (value == NULL)
1756 printf("\n");
1757 else {
1758 printf(" %s\n", value);
1759 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001760 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001761#ifdef LIBXML_PATTERN_ENABLED
1762 if (patternc) {
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001763 xmlChar *path = NULL;
1764 int match = -1;
Daniel Veillardf1edb102009-08-10 14:43:18 +02001765
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001766 if (type == XML_READER_TYPE_ELEMENT) {
1767 /* do the check only on element start */
1768 match = xmlPatternMatch(patternc, xmlTextReaderCurrentNode(reader));
1769
1770 if (match) {
Daniel Veillardf1edb102009-08-10 14:43:18 +02001771#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001772 path = xmlGetNodePath(xmlTextReaderCurrentNode(reader));
1773 printf("Node %s matches pattern %s\n", path, pattern);
Daniel Veillardf1edb102009-08-10 14:43:18 +02001774#else
1775 printf("Node %s matches pattern %s\n",
1776 xmlTextReaderConstName(reader), pattern);
1777#endif
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001778 }
1779 }
1780 if (patstream != NULL) {
1781 int ret;
1782
1783 if (type == XML_READER_TYPE_ELEMENT) {
1784 ret = xmlStreamPush(patstream,
1785 xmlTextReaderConstLocalName(reader),
1786 xmlTextReaderConstNamespaceUri(reader));
1787 if (ret < 0) {
1788 fprintf(stderr, "xmlStreamPush() failure\n");
1789 xmlFreeStreamCtxt(patstream);
1790 patstream = NULL;
1791 } else if (ret != match) {
Daniel Veillardf1edb102009-08-10 14:43:18 +02001792#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001793 if (path == NULL) {
1794 path = xmlGetNodePath(
1795 xmlTextReaderCurrentNode(reader));
1796 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02001797#endif
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001798 fprintf(stderr,
1799 "xmlPatternMatch and xmlStreamPush disagree\n");
Daniel Veillardf1edb102009-08-10 14:43:18 +02001800 if (path != NULL)
1801 fprintf(stderr, " pattern %s node %s\n",
1802 pattern, path);
1803 else
1804 fprintf(stderr, " pattern %s node %s\n",
1805 pattern, xmlTextReaderConstName(reader));
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001806 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001807
Daniel Veillardf1edb102009-08-10 14:43:18 +02001808 }
Daniel Veillard16ef8002005-01-31 00:27:50 +00001809 if ((type == XML_READER_TYPE_END_ELEMENT) ||
1810 ((type == XML_READER_TYPE_ELEMENT) && (empty))) {
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001811 ret = xmlStreamPop(patstream);
1812 if (ret < 0) {
1813 fprintf(stderr, "xmlStreamPop() failure\n");
1814 xmlFreeStreamCtxt(patstream);
1815 patstream = NULL;
1816 }
1817 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001818 }
Daniel Veillardf9d16912005-01-30 22:36:30 +00001819 if (path != NULL)
1820 xmlFree(path);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001821 }
1822#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001823}
1824
1825static void streamFile(char *filename) {
1826 xmlTextReaderPtr reader;
1827 int ret;
Daniel Richard G5706b6d2012-08-06 11:32:54 +08001828#ifdef HAVE_MMAP
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001829 int fd = -1;
1830 struct stat info;
1831 const char *base = NULL;
1832 xmlParserInputBufferPtr input = NULL;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001833
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001834 if (memory) {
Daniel Veillardf1edb102009-08-10 14:43:18 +02001835 if (stat(filename, &info) < 0)
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001836 return;
1837 if ((fd = open(filename, O_RDONLY)) < 0)
1838 return;
1839 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillardb98c6a02013-07-12 12:08:40 +08001840 if (base == (void *) MAP_FAILED) {
1841 close(fd);
1842 fprintf(stderr, "mmap failure for file %s\n", filename);
1843 progresult = XMLLINT_ERR_RDFILE;
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001844 return;
Daniel Veillardb98c6a02013-07-12 12:08:40 +08001845 }
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001846
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001847 reader = xmlReaderForMemory(base, info.st_size, filename,
1848 NULL, options);
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001849 } else
1850#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001851 reader = xmlReaderForFile(filename, NULL, options);
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001852#ifdef LIBXML_PATTERN_ENABLED
Daniel Veillardd4301ab2005-02-03 22:24:10 +00001853 if (pattern != NULL) {
1854 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
1855 if (patternc == NULL) {
1856 xmlGenericError(xmlGenericErrorContext,
1857 "Pattern %s failed to compile\n", pattern);
1858 progresult = XMLLINT_ERR_SCHEMAPAT;
1859 pattern = NULL;
1860 }
1861 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001862 if (patternc != NULL) {
1863 patstream = xmlPatternGetStreamCtxt(patternc);
1864 if (patstream != NULL) {
1865 ret = xmlStreamPush(patstream, NULL, NULL);
1866 if (ret < 0) {
1867 fprintf(stderr, "xmlStreamPush() failure\n");
1868 xmlFreeStreamCtxt(patstream);
1869 patstream = NULL;
1870 }
1871 }
1872 }
1873#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001874
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001875
Daniel Veillard7704fb12003-01-03 16:19:51 +00001876 if (reader != NULL) {
Daniel Veillard4432df22003-09-28 18:58:27 +00001877#ifdef LIBXML_VALID_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00001878 if (valid)
1879 xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
Daniel Veillardce192eb2003-04-16 15:58:05 +00001880 else
Daniel Veillard4432df22003-09-28 18:58:27 +00001881#endif /* LIBXML_VALID_ENABLED */
Daniel Veillarde4d16d72012-12-21 10:58:14 +08001882 if (loaddtd)
1883 xmlTextReaderSetParserProp(reader, XML_PARSER_LOADDTD, 1);
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001884#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +00001885 if (relaxng != NULL) {
Daniel Veillard81514ba2003-09-16 23:17:26 +00001886 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001887 startTimer();
1888 }
1889 ret = xmlTextReaderRelaxNGValidate(reader, relaxng);
1890 if (ret < 0) {
1891 xmlGenericError(xmlGenericErrorContext,
1892 "Relax-NG schema %s failed to compile\n", relaxng);
William M. Brack8304d872004-06-08 13:29:32 +00001893 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillardce192eb2003-04-16 15:58:05 +00001894 relaxng = NULL;
1895 }
Daniel Veillard81514ba2003-09-16 23:17:26 +00001896 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001897 endTimer("Compiling the schemas");
1898 }
1899 }
Daniel Veillardf10ae122005-07-10 19:03:16 +00001900 if (schema != NULL) {
1901 if ((timing) && (!repeat)) {
1902 startTimer();
1903 }
1904 ret = xmlTextReaderSchemaValidate(reader, schema);
1905 if (ret < 0) {
1906 xmlGenericError(xmlGenericErrorContext,
1907 "XSD schema %s failed to compile\n", schema);
1908 progresult = XMLLINT_ERR_SCHEMACOMP;
1909 schema = NULL;
1910 }
1911 if ((timing) && (!repeat)) {
1912 endTimer("Compiling the schemas");
1913 }
1914 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001915#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001916
1917 /*
1918 * Process all nodes in sequence
1919 */
Daniel Veillard81514ba2003-09-16 23:17:26 +00001920 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001921 startTimer();
1922 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001923 ret = xmlTextReaderRead(reader);
1924 while (ret == 1) {
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001925 if ((debug)
1926#ifdef LIBXML_PATTERN_ENABLED
1927 || (patternc)
1928#endif
1929 )
Daniel Veillard7704fb12003-01-03 16:19:51 +00001930 processNode(reader);
1931 ret = xmlTextReaderRead(reader);
1932 }
Daniel Veillard81514ba2003-09-16 23:17:26 +00001933 if ((timing) && (!repeat)) {
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001934#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf54cd532004-02-25 11:52:31 +00001935 if (relaxng != NULL)
Daniel Veillard49138f12004-02-19 12:58:36 +00001936 endTimer("Parsing and validating");
1937 else
Daniel Veillardf54cd532004-02-25 11:52:31 +00001938#endif
Daniel Veillard4432df22003-09-28 18:58:27 +00001939#ifdef LIBXML_VALID_ENABLED
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001940 if (valid)
Daniel Veillardce192eb2003-04-16 15:58:05 +00001941 endTimer("Parsing and validating");
1942 else
Daniel Veillard4432df22003-09-28 18:58:27 +00001943#endif
Daniel Veillardf54cd532004-02-25 11:52:31 +00001944 endTimer("Parsing");
Daniel Veillardce192eb2003-04-16 15:58:05 +00001945 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001946
Daniel Veillard4432df22003-09-28 18:58:27 +00001947#ifdef LIBXML_VALID_ENABLED
Daniel Veillardf6bad792003-04-11 19:38:54 +00001948 if (valid) {
1949 if (xmlTextReaderIsValid(reader) != 1) {
1950 xmlGenericError(xmlGenericErrorContext,
1951 "Document %s does not validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001952 progresult = XMLLINT_ERR_VALID;
Daniel Veillardf6bad792003-04-11 19:38:54 +00001953 }
1954 }
Daniel Veillard4432df22003-09-28 18:58:27 +00001955#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001956#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf10ae122005-07-10 19:03:16 +00001957 if ((relaxng != NULL) || (schema != NULL)) {
Daniel Veillardf4e55762003-04-15 23:32:22 +00001958 if (xmlTextReaderIsValid(reader) != 1) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001959 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001960 progresult = XMLLINT_ERR_VALID;
Daniel Veillardf4e55762003-04-15 23:32:22 +00001961 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001962 fprintf(stderr, "%s validates\n", filename);
Daniel Veillardf4e55762003-04-15 23:32:22 +00001963 }
1964 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001965#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001966 /*
1967 * Done, cleanup and status
1968 */
1969 xmlFreeTextReader(reader);
1970 if (ret != 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001971 fprintf(stderr, "%s : failed to parse\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001972 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001973 }
1974 } else {
1975 fprintf(stderr, "Unable to open %s\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001976 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001977 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001978#ifdef LIBXML_PATTERN_ENABLED
1979 if (patstream != NULL) {
1980 xmlFreeStreamCtxt(patstream);
1981 patstream = NULL;
1982 }
1983#endif
Daniel Richard G5706b6d2012-08-06 11:32:54 +08001984#ifdef HAVE_MMAP
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001985 if (memory) {
1986 xmlFreeParserInputBuffer(input);
1987 munmap((char *) base, info.st_size);
1988 close(fd);
1989 }
1990#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001991}
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001992
1993static void walkDoc(xmlDocPtr doc) {
1994 xmlTextReaderPtr reader;
1995 int ret;
1996
Daniel Veillardd4301ab2005-02-03 22:24:10 +00001997#ifdef LIBXML_PATTERN_ENABLED
1998 xmlNodePtr root;
1999 const xmlChar *namespaces[22];
2000 int i;
2001 xmlNsPtr ns;
2002
2003 root = xmlDocGetRootElement(doc);
2004 for (ns = root->nsDef, i = 0;ns != NULL && i < 20;ns=ns->next) {
2005 namespaces[i++] = ns->href;
2006 namespaces[i++] = ns->prefix;
2007 }
2008 namespaces[i++] = NULL;
Daniel Veillard13cee4e2009-09-05 14:52:55 +02002009 namespaces[i] = NULL;
Daniel Veillardd4301ab2005-02-03 22:24:10 +00002010
2011 if (pattern != NULL) {
2012 patternc = xmlPatterncompile((const xmlChar *) pattern, doc->dict,
2013 0, &namespaces[0]);
2014 if (patternc == NULL) {
2015 xmlGenericError(xmlGenericErrorContext,
2016 "Pattern %s failed to compile\n", pattern);
2017 progresult = XMLLINT_ERR_SCHEMAPAT;
2018 pattern = NULL;
2019 }
2020 }
Daniel Veillard2b2e02d2005-02-05 23:20:22 +00002021 if (patternc != NULL) {
2022 patstream = xmlPatternGetStreamCtxt(patternc);
2023 if (patstream != NULL) {
2024 ret = xmlStreamPush(patstream, NULL, NULL);
2025 if (ret < 0) {
2026 fprintf(stderr, "xmlStreamPush() failure\n");
2027 xmlFreeStreamCtxt(patstream);
2028 patstream = NULL;
2029 }
2030 }
2031 }
Daniel Veillardd4301ab2005-02-03 22:24:10 +00002032#endif /* LIBXML_PATTERN_ENABLED */
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002033 reader = xmlReaderWalker(doc);
2034 if (reader != NULL) {
2035 if ((timing) && (!repeat)) {
2036 startTimer();
2037 }
2038 ret = xmlTextReaderRead(reader);
2039 while (ret == 1) {
Daniel Veillardb3de70c2003-12-02 22:32:15 +00002040 if ((debug)
2041#ifdef LIBXML_PATTERN_ENABLED
2042 || (patternc)
2043#endif
2044 )
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002045 processNode(reader);
2046 ret = xmlTextReaderRead(reader);
2047 }
2048 if ((timing) && (!repeat)) {
2049 endTimer("walking through the doc");
2050 }
2051 xmlFreeTextReader(reader);
2052 if (ret != 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002053 fprintf(stderr, "failed to walk through the doc\n");
William M. Brack8304d872004-06-08 13:29:32 +00002054 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002055 }
2056 } else {
2057 fprintf(stderr, "Failed to crate a reader from the document\n");
William M. Brack8304d872004-06-08 13:29:32 +00002058 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002059 }
Daniel Veillard2b2e02d2005-02-05 23:20:22 +00002060#ifdef LIBXML_PATTERN_ENABLED
2061 if (patstream != NULL) {
2062 xmlFreeStreamCtxt(patstream);
2063 patstream = NULL;
2064 }
2065#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002066}
Daniel Veillard81273902003-09-30 00:43:48 +00002067#endif /* LIBXML_READER_ENABLED */
Daniel Veillard7704fb12003-01-03 16:19:51 +00002068
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002069#ifdef LIBXML_XPATH_ENABLED
2070/************************************************************************
2071 * *
2072 * XPath Query *
2073 * *
2074 ************************************************************************/
2075
2076static void doXPathDump(xmlXPathObjectPtr cur) {
2077 switch(cur->type) {
2078 case XPATH_NODESET: {
2079 int i;
2080 xmlNodePtr node;
2081#ifdef LIBXML_OUTPUT_ENABLED
2082 xmlSaveCtxtPtr ctxt;
2083
Daniel Veillardbdc64d62012-03-27 14:41:37 +08002084 if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr <= 0)) {
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002085 fprintf(stderr, "XPath set is empty\n");
2086 progresult = XMLLINT_ERR_XPATH;
2087 break;
2088 }
2089 ctxt = xmlSaveToFd(1, NULL, 0);
2090 if (ctxt == NULL) {
2091 fprintf(stderr, "Out of memory for XPath\n");
2092 progresult = XMLLINT_ERR_MEM;
2093 return;
2094 }
2095 for (i = 0;i < cur->nodesetval->nodeNr;i++) {
2096 node = cur->nodesetval->nodeTab[i];
2097 xmlSaveTree(ctxt, node);
2098 }
2099 xmlSaveClose(ctxt);
2100#else
2101 printf("xpath returned %d nodes\n", cur->nodesetval->nodeNr);
2102#endif
2103 break;
2104 }
2105 case XPATH_BOOLEAN:
2106 if (cur->boolval) printf("true");
2107 else printf("false");
2108 break;
2109 case XPATH_NUMBER:
2110 switch (xmlXPathIsInf(cur->floatval)) {
2111 case 1:
2112 printf("Infinity");
2113 break;
2114 case -1:
2115 printf("-Infinity");
2116 break;
2117 default:
2118 if (xmlXPathIsNaN(cur->floatval)) {
2119 printf("NaN");
2120 } else {
2121 printf("%0g", cur->floatval);
2122 }
2123 }
2124 break;
2125 case XPATH_STRING:
2126 printf("%s", (const char *) cur->stringval);
2127 break;
2128 case XPATH_UNDEFINED:
2129 fprintf(stderr, "XPath Object is uninitialized\n");
2130 progresult = XMLLINT_ERR_XPATH;
2131 break;
2132 default:
2133 fprintf(stderr, "XPath object of unexpected type\n");
2134 progresult = XMLLINT_ERR_XPATH;
2135 break;
2136 }
2137}
2138
2139static void doXPathQuery(xmlDocPtr doc, const char *query) {
2140 xmlXPathContextPtr ctxt;
2141 xmlXPathObjectPtr res;
2142
2143 ctxt = xmlXPathNewContext(doc);
2144 if (ctxt == NULL) {
2145 fprintf(stderr, "Out of memory for XPath\n");
2146 progresult = XMLLINT_ERR_MEM;
2147 return;
2148 }
Daniel Veillard2e1eaca2012-05-25 16:44:20 +08002149 ctxt->node = (xmlNodePtr) doc;
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002150 res = xmlXPathEval(BAD_CAST query, ctxt);
2151 xmlXPathFreeContext(ctxt);
2152
2153 if (res == NULL) {
2154 fprintf(stderr, "XPath evaluation failure\n");
2155 progresult = XMLLINT_ERR_XPATH;
2156 return;
2157 }
2158 doXPathDump(res);
2159 xmlXPathFreeObject(res);
2160}
2161#endif /* LIBXML_XPATH_ENABLED */
2162
Daniel Veillard7704fb12003-01-03 16:19:51 +00002163/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +02002164 * *
2165 * Tree Test processing *
2166 * *
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002167 ************************************************************************/
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002168static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
Daniel Veillard652327a2003-09-29 18:02:38 +00002169 xmlDocPtr doc = NULL;
2170#ifdef LIBXML_TREE_ENABLED
2171 xmlDocPtr tmp;
2172#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002173
Daniel Veillard48b2f892001-02-25 16:11:03 +00002174 if ((timing) && (!repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00002175 startTimer();
Daniel Veillardf1edb102009-08-10 14:43:18 +02002176
Daniel Veillard48b2f892001-02-25 16:11:03 +00002177
Daniel Veillard652327a2003-09-29 18:02:38 +00002178#ifdef LIBXML_TREE_ENABLED
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002179 if (filename == NULL) {
2180 if (generate) {
2181 xmlNodePtr n;
2182
2183 doc = xmlNewDoc(BAD_CAST "1.0");
Daniel Veillard95ddcd32004-10-26 21:53:55 +00002184 n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002185 xmlNodeSetContent(n, BAD_CAST "abc");
2186 xmlDocSetRootElement(doc, n);
2187 }
2188 }
Daniel Veillard652327a2003-09-29 18:02:38 +00002189#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002190#ifdef LIBXML_HTML_ENABLED
Daniel Veillard73b013f2003-09-30 12:36:01 +00002191#ifdef LIBXML_PUSH_ENABLED
William M. Brack78637da2003-07-31 14:47:38 +00002192 else if ((html) && (push)) {
2193 FILE *f;
2194
William M. Brack3403add2004-06-27 02:07:51 +00002195#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2196 f = fopen(filename, "rb");
Patrick Monnerat1c43f432013-12-12 15:12:53 +08002197#elif defined(__OS400__)
2198 f = fopen(filename, "rb");
William M. Brack3403add2004-06-27 02:07:51 +00002199#else
2200 f = fopen(filename, "r");
2201#endif
William M. Brack78637da2003-07-31 14:47:38 +00002202 if (f != NULL) {
Daniel Veillard1abd2212012-10-25 15:37:50 +08002203 int res;
William M. Brack78637da2003-07-31 14:47:38 +00002204 char chars[4096];
2205 htmlParserCtxtPtr ctxt;
2206
William M. Brack78637da2003-07-31 14:47:38 +00002207 res = fread(chars, 1, 4, f);
2208 if (res > 0) {
2209 ctxt = htmlCreatePushParserCtxt(NULL, NULL,
William M. Brack1d75c8a2003-10-27 13:48:16 +00002210 chars, res, filename, XML_CHAR_ENCODING_NONE);
Arnold Hendriks826bc322013-11-29 14:12:12 +08002211 xmlCtxtUseOptions(ctxt, options);
Daniel Veillard1abd2212012-10-25 15:37:50 +08002212 while ((res = fread(chars, 1, pushsize, f)) > 0) {
William M. Brack78637da2003-07-31 14:47:38 +00002213 htmlParseChunk(ctxt, chars, res, 0);
2214 }
2215 htmlParseChunk(ctxt, chars, 0, 1);
2216 doc = ctxt->myDoc;
2217 htmlFreeParserCtxt(ctxt);
2218 }
2219 fclose(f);
2220 }
2221 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00002222#endif /* LIBXML_PUSH_ENABLED */
Daniel Richard G5706b6d2012-08-06 11:32:54 +08002223#ifdef HAVE_MMAP
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002224 else if ((html) && (memory)) {
2225 int fd;
2226 struct stat info;
2227 const char *base;
Daniel Veillardf1edb102009-08-10 14:43:18 +02002228 if (stat(filename, &info) < 0)
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002229 return;
2230 if ((fd = open(filename, O_RDONLY)) < 0)
2231 return;
2232 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillardb98c6a02013-07-12 12:08:40 +08002233 if (base == (void *) MAP_FAILED) {
2234 close(fd);
2235 fprintf(stderr, "mmap failure for file %s\n", filename);
2236 progresult = XMLLINT_ERR_RDFILE;
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002237 return;
Daniel Veillardb98c6a02013-07-12 12:08:40 +08002238 }
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002239
2240 doc = htmlReadMemory((char *) base, info.st_size, filename,
2241 NULL, options);
Daniel Veillardf1edb102009-08-10 14:43:18 +02002242
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002243 munmap((char *) base, info.st_size);
2244 close(fd);
2245 }
2246#endif
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002247 else if (html) {
Daniel Veillard9475a352003-09-26 12:47:50 +00002248 doc = htmlReadFile(filename, NULL, options);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002249 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002250#endif /* LIBXML_HTML_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002251 else {
Daniel Veillard73b013f2003-09-30 12:36:01 +00002252#ifdef LIBXML_PUSH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002253 /*
2254 * build an XML tree from a string;
2255 */
2256 if (push) {
2257 FILE *f;
2258
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002259 /* '-' Usually means stdin -<sven@zen.org> */
2260 if ((filename[0] == '-') && (filename[1] == 0)) {
2261 f = stdin;
2262 } else {
William M. Brack3403add2004-06-27 02:07:51 +00002263#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2264 f = fopen(filename, "rb");
Patrick Monnerat1c43f432013-12-12 15:12:53 +08002265#elif defined(__OS400__)
2266 f = fopen(filename, "rb");
William M. Brack3403add2004-06-27 02:07:51 +00002267#else
2268 f = fopen(filename, "r");
2269#endif
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002270 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002271 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +00002272 int ret;
Daniel Veillarda880b122003-04-21 21:36:41 +00002273 int res, size = 1024;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002274 char chars[1024];
2275 xmlParserCtxtPtr ctxt;
2276
Daniel Veillarda880b122003-04-21 21:36:41 +00002277 /* if (repeat) size = 1024; */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002278 res = fread(chars, 1, 4, f);
2279 if (res > 0) {
2280 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
2281 chars, res, filename);
Daniel Veillard500a1de2004-03-22 15:22:58 +00002282 xmlCtxtUseOptions(ctxt, options);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002283 while ((res = fread(chars, 1, size, f)) > 0) {
2284 xmlParseChunk(ctxt, chars, res, 0);
2285 }
2286 xmlParseChunk(ctxt, chars, 0, 1);
2287 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +00002288 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002289 xmlFreeParserCtxt(ctxt);
Daniel Veillarde715dd22000-08-29 18:29:38 +00002290 if (!ret) {
2291 xmlFreeDoc(doc);
2292 doc = NULL;
2293 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002294 }
Daniel Veillard84bff682009-09-11 15:30:19 +02002295 if (f != stdin)
2296 fclose(f);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002297 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00002298 } else
2299#endif /* LIBXML_PUSH_ENABLED */
2300 if (testIO) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002301 if ((filename[0] == '-') && (filename[1] == 0)) {
Daniel Veillard60942de2003-09-25 21:05:58 +00002302 doc = xmlReadFd(0, NULL, NULL, options);
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002303 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002304 FILE *f;
Daniel Veillard5e873c42000-04-12 13:27:38 +00002305
William M. Brack3403add2004-06-27 02:07:51 +00002306#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2307 f = fopen(filename, "rb");
Patrick Monnerat1c43f432013-12-12 15:12:53 +08002308#elif defined(__OS400__)
2309 f = fopen(filename, "rb");
William M. Brack3403add2004-06-27 02:07:51 +00002310#else
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002311 f = fopen(filename, "r");
William M. Brack3403add2004-06-27 02:07:51 +00002312#endif
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002313 if (f != NULL) {
2314 if (rectxt == NULL)
2315 doc = xmlReadIO((xmlInputReadCallback) myRead,
2316 (xmlInputCloseCallback) myClose, f,
Daniel Veillard60942de2003-09-25 21:05:58 +00002317 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002318 else
2319 doc = xmlCtxtReadIO(rectxt,
2320 (xmlInputReadCallback) myRead,
2321 (xmlInputCloseCallback) myClose, f,
Daniel Veillard60942de2003-09-25 21:05:58 +00002322 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002323 } else
Daniel Veillard5e873c42000-04-12 13:27:38 +00002324 doc = NULL;
Daniel Veillard5e873c42000-04-12 13:27:38 +00002325 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002326 } else if (htmlout) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002327 xmlParserCtxtPtr ctxt;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002328
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002329 if (rectxt == NULL)
2330 ctxt = xmlNewParserCtxt();
2331 else
2332 ctxt = rectxt;
Daniel Veillardf1edb102009-08-10 14:43:18 +02002333 if (ctxt == NULL) {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002334 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +00002335 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002336 ctxt->sax->error = xmlHTMLError;
2337 ctxt->sax->warning = xmlHTMLWarning;
2338 ctxt->vctxt.error = xmlHTMLValidityError;
2339 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002340
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002341 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002342
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002343 if (rectxt == NULL)
2344 xmlFreeParserCtxt(ctxt);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002345 }
Daniel Richard G5706b6d2012-08-06 11:32:54 +08002346#ifdef HAVE_MMAP
Daniel Veillard46e370e2000-07-21 20:32:03 +00002347 } else if (memory) {
2348 int fd;
2349 struct stat info;
2350 const char *base;
Daniel Veillardf1edb102009-08-10 14:43:18 +02002351 if (stat(filename, &info) < 0)
Daniel Veillard46e370e2000-07-21 20:32:03 +00002352 return;
2353 if ((fd = open(filename, O_RDONLY)) < 0)
2354 return;
2355 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillarda75a0092013-05-08 13:45:48 +08002356 if (base == (void *) MAP_FAILED) {
Daniel Veillardb98c6a02013-07-12 12:08:40 +08002357 close(fd);
Daniel Veillarda75a0092013-05-08 13:45:48 +08002358 fprintf(stderr, "mmap failure for file %s\n", filename);
2359 progresult = XMLLINT_ERR_RDFILE;
Daniel Veillard46e370e2000-07-21 20:32:03 +00002360 return;
Daniel Veillarda75a0092013-05-08 13:45:48 +08002361 }
Daniel Veillard46e370e2000-07-21 20:32:03 +00002362
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002363 if (rectxt == NULL)
Daniel Veillard60942de2003-09-25 21:05:58 +00002364 doc = xmlReadMemory((char *) base, info.st_size,
2365 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002366 else
Daniel Veillard60942de2003-09-25 21:05:58 +00002367 doc = xmlCtxtReadMemory(rectxt, (char *) base, info.st_size,
2368 filename, NULL, options);
Daniel Veillardf1edb102009-08-10 14:43:18 +02002369
Daniel Veillard46e370e2000-07-21 20:32:03 +00002370 munmap((char *) base, info.st_size);
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002371 close(fd);
Daniel Veillard46e370e2000-07-21 20:32:03 +00002372#endif
Daniel Veillard4432df22003-09-28 18:58:27 +00002373#ifdef LIBXML_VALID_ENABLED
Daniel Veillardea7751d2002-12-20 00:16:24 +00002374 } else if (valid) {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002375 xmlParserCtxtPtr ctxt = NULL;
Daniel Veillardea7751d2002-12-20 00:16:24 +00002376
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002377 if (rectxt == NULL)
2378 ctxt = xmlNewParserCtxt();
2379 else
2380 ctxt = rectxt;
Daniel Veillardf1edb102009-08-10 14:43:18 +02002381 if (ctxt == NULL) {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002382 doc = NULL;
Daniel Veillardea7751d2002-12-20 00:16:24 +00002383 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002384 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
2385
2386 if (ctxt->valid == 0)
William M. Brack8304d872004-06-08 13:29:32 +00002387 progresult = XMLLINT_ERR_RDFILE;
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002388 if (rectxt == NULL)
2389 xmlFreeParserCtxt(ctxt);
Daniel Veillardea7751d2002-12-20 00:16:24 +00002390 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002391#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardea7751d2002-12-20 00:16:24 +00002392 } else {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002393 if (rectxt != NULL)
2394 doc = xmlCtxtReadFile(rectxt, filename, NULL, options);
Daniel Veillard81562d22005-06-15 13:27:56 +00002395 else {
2396#ifdef LIBXML_SAX1_ENABLED
2397 if (sax1)
2398 doc = xmlParseFile(filename);
2399 else
2400#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002401 doc = xmlReadFile(filename, NULL, options);
Daniel Veillard81562d22005-06-15 13:27:56 +00002402 }
Daniel Veillardea7751d2002-12-20 00:16:24 +00002403 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002404 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002405
Daniel Veillard88a172f2000-08-04 18:23:10 +00002406 /*
2407 * If we don't have a document we might as well give up. Do we
2408 * want an error message here? <sven@zen.org> */
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002409 if (doc == NULL) {
William M. Brack8304d872004-06-08 13:29:32 +00002410 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard88a172f2000-08-04 18:23:10 +00002411 return;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002412 }
2413
Daniel Veillard48b2f892001-02-25 16:11:03 +00002414 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002415 endTimer("Parsing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002416 }
2417
Daniel Veillard29e43992001-12-13 22:21:58 +00002418 /*
2419 * Remove DOCTYPE nodes
2420 */
2421 if (dropdtd) {
2422 xmlDtdPtr dtd;
2423
2424 dtd = xmlGetIntSubset(doc);
2425 if (dtd != NULL) {
2426 xmlUnlinkNode((xmlNodePtr)dtd);
2427 xmlFreeDtd(dtd);
2428 }
2429 }
2430
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002431#ifdef LIBXML_XINCLUDE_ENABLED
Daniel Veillard48b2f892001-02-25 16:11:03 +00002432 if (xinclude) {
2433 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002434 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002435 }
William M. Brack4e1c2db2005-02-11 10:58:55 +00002436 if (xmlXIncludeProcessFlags(doc, options) < 0)
2437 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard48b2f892001-02-25 16:11:03 +00002438 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002439 endTimer("Xinclude processing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002440 }
2441 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002442#endif
Daniel Veillard88a172f2000-08-04 18:23:10 +00002443
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002444#ifdef LIBXML_XPATH_ENABLED
2445 if (xpathquery != NULL) {
2446 doXPathQuery(doc, xpathquery);
2447 }
2448#endif
2449
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002450#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00002451#ifdef LIBXML_XPATH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002452 /*
Daniel Veillardcbaf3992001-12-31 16:16:02 +00002453 * shell interaction
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002454 */
Daniel Veillard26a45c82006-10-20 12:55:34 +00002455 if (shell) {
2456 xmlXPathOrderDocElems(doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002457 xmlShell(doc, filename, xmlShellReadline, stdout);
Daniel Veillard26a45c82006-10-20 12:55:34 +00002458 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002459#endif
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00002460#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002461
Daniel Veillard652327a2003-09-29 18:02:38 +00002462#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002463 /*
2464 * test intermediate copy if needed.
2465 */
2466 if (copy) {
2467 tmp = doc;
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002468 if (timing) {
2469 startTimer();
2470 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002471 doc = xmlCopyDoc(doc, 1);
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002472 if (timing) {
2473 endTimer("Copying");
2474 }
2475 if (timing) {
2476 startTimer();
2477 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002478 xmlFreeDoc(tmp);
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002479 if (timing) {
2480 endTimer("Freeing original");
2481 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002482 }
Daniel Veillard652327a2003-09-29 18:02:38 +00002483#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002484
Daniel Veillard4432df22003-09-28 18:58:27 +00002485#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002486 if ((insert) && (!html)) {
2487 const xmlChar* list[256];
2488 int nb, i;
2489 xmlNodePtr node;
2490
2491 if (doc->children != NULL) {
2492 node = doc->children;
2493 while ((node != NULL) && (node->last == NULL)) node = node->next;
2494 if (node != NULL) {
2495 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
2496 if (nb < 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002497 fprintf(stderr, "could not get valid list of elements\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002498 } else if (nb == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002499 fprintf(stderr, "No element can be inserted under root\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002500 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002501 fprintf(stderr, "%d element types can be inserted under root:\n",
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002502 nb);
2503 for (i = 0;i < nb;i++) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002504 fprintf(stderr, "%s\n", (char *) list[i]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002505 }
2506 }
2507 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02002508 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002509 }else
2510#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002511#ifdef LIBXML_READER_ENABLED
2512 if (walker) {
2513 walkDoc(doc);
2514 }
2515#endif /* LIBXML_READER_ENABLED */
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002516#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard4432df22003-09-28 18:58:27 +00002517 if (noout == 0) {
Daniel Veillard3df01182003-12-10 10:17:51 +00002518 int ret;
2519
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002520 /*
2521 * print it.
2522 */
2523#ifdef LIBXML_DEBUG_ENABLED
2524 if (!debug) {
2525#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00002526 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002527 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002528 }
Daniel Veillard656ce942004-04-30 23:11:45 +00002529#ifdef LIBXML_HTML_ENABLED
Daniel Veillard42fd4122003-11-04 08:47:48 +00002530 if ((html) && (!xmlout)) {
2531 if (compress) {
2532 htmlSaveFile(output ? output : "-", doc);
2533 }
2534 else if (encoding != NULL) {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002535 if (format == 1) {
Daniel Veillard42fd4122003-11-04 08:47:48 +00002536 htmlSaveFileFormat(output ? output : "-", doc, encoding, 1);
2537 }
2538 else {
2539 htmlSaveFileFormat(output ? output : "-", doc, encoding, 0);
2540 }
2541 }
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002542 else if (format == 1) {
Daniel Veillard42fd4122003-11-04 08:47:48 +00002543 htmlSaveFileFormat(output ? output : "-", doc, NULL, 1);
2544 }
2545 else {
2546 FILE *out;
2547 if (output == NULL)
2548 out = stdout;
2549 else {
2550 out = fopen(output,"wb");
2551 }
2552 if (out != NULL) {
2553 if (htmlDocDump(out, doc) < 0)
William M. Brack8304d872004-06-08 13:29:32 +00002554 progresult = XMLLINT_ERR_OUT;
Daniel Veillard42fd4122003-11-04 08:47:48 +00002555
2556 if (output != NULL)
2557 fclose(out);
2558 } else {
2559 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00002560 progresult = XMLLINT_ERR_OUT;
Daniel Veillard42fd4122003-11-04 08:47:48 +00002561 }
2562 }
2563 if ((timing) && (!repeat)) {
2564 endTimer("Saving");
2565 }
2566 } else
2567#endif
Daniel Veillard25048d82004-08-14 22:37:54 +00002568#ifdef LIBXML_C14N_ENABLED
2569 if (canonical) {
2570 xmlChar *result = NULL;
2571 int size;
2572
Aleksey Sanin83868242009-07-09 10:26:22 +02002573 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_0, NULL, 1, &result);
2574 if (size >= 0) {
Stefan Kostdff8d0f2011-05-09 12:14:59 +03002575 if (write(1, result, size) == -1) {
2576 fprintf(stderr, "Can't write data\n");
2577 }
Aleksey Sanin83868242009-07-09 10:26:22 +02002578 xmlFree(result);
2579 } else {
2580 fprintf(stderr, "Failed to canonicalize\n");
2581 progresult = XMLLINT_ERR_OUT;
2582 }
Sérgio Batistad9ea9132014-06-09 22:10:15 +08002583 } else if (canonical_11) {
Aleksey Sanin83868242009-07-09 10:26:22 +02002584 xmlChar *result = NULL;
2585 int size;
2586
2587 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_1, NULL, 1, &result);
Daniel Veillard25048d82004-08-14 22:37:54 +00002588 if (size >= 0) {
Stefan Kostdff8d0f2011-05-09 12:14:59 +03002589 if (write(1, result, size) == -1) {
2590 fprintf(stderr, "Can't write data\n");
2591 }
Daniel Veillard25048d82004-08-14 22:37:54 +00002592 xmlFree(result);
2593 } else {
2594 fprintf(stderr, "Failed to canonicalize\n");
2595 progresult = XMLLINT_ERR_OUT;
2596 }
2597 } else
Aleksey Sanin2650df12005-06-06 17:16:50 +00002598 if (exc_canonical) {
2599 xmlChar *result = NULL;
2600 int size;
2601
Aleksey Sanin83868242009-07-09 10:26:22 +02002602 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_EXCLUSIVE_1_0, NULL, 1, &result);
Aleksey Sanin2650df12005-06-06 17:16:50 +00002603 if (size >= 0) {
Stefan Kostdff8d0f2011-05-09 12:14:59 +03002604 if (write(1, result, size) == -1) {
2605 fprintf(stderr, "Can't write data\n");
2606 }
Aleksey Sanin2650df12005-06-06 17:16:50 +00002607 xmlFree(result);
2608 } else {
2609 fprintf(stderr, "Failed to canonicalize\n");
2610 progresult = XMLLINT_ERR_OUT;
2611 }
2612 } else
Daniel Veillard25048d82004-08-14 22:37:54 +00002613#endif
Daniel Richard G5706b6d2012-08-06 11:32:54 +08002614#ifdef HAVE_MMAP
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002615 if (memory) {
2616 xmlChar *result;
2617 int len;
2618
2619 if (encoding != NULL) {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002620 if (format == 1) {
Daniel Veillardd536f702001-11-08 17:32:47 +00002621 xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
Daniel Veillardf1edb102009-08-10 14:43:18 +02002622 } else {
Daniel Veillardd536f702001-11-08 17:32:47 +00002623 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
2624 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002625 } else {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002626 if (format == 1)
Daniel Veillard90493a92001-08-14 14:12:47 +00002627 xmlDocDumpFormatMemory(doc, &result, &len, 1);
2628 else
2629 xmlDocDumpMemory(doc, &result, &len);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002630 }
2631 if (result == NULL) {
2632 fprintf(stderr, "Failed to save\n");
Daniel Veillard25048d82004-08-14 22:37:54 +00002633 progresult = XMLLINT_ERR_OUT;
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002634 } else {
Stefan Kostdff8d0f2011-05-09 12:14:59 +03002635 if (write(1, result, len) == -1) {
2636 fprintf(stderr, "Can't write data\n");
2637 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002638 xmlFree(result);
2639 }
Daniel Veillarddab39b52006-10-16 23:22:10 +00002640
Daniel Veillard3b2c2612001-04-04 00:09:00 +00002641 } else
Daniel Richard G5706b6d2012-08-06 11:32:54 +08002642#endif /* HAVE_MMAP */
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002643 if (compress) {
2644 xmlSaveFile(output ? output : "-", doc);
Daniel Veillarddab39b52006-10-16 23:22:10 +00002645 } else if (oldout) {
2646 if (encoding != NULL) {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002647 if (format == 1) {
Daniel Veillarddab39b52006-10-16 23:22:10 +00002648 ret = xmlSaveFormatFileEnc(output ? output : "-", doc,
2649 encoding, 1);
2650 }
2651 else {
2652 ret = xmlSaveFileEnc(output ? output : "-", doc,
2653 encoding);
2654 }
2655 if (ret < 0) {
2656 fprintf(stderr, "failed save to %s\n",
2657 output ? output : "-");
2658 progresult = XMLLINT_ERR_OUT;
2659 }
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002660 } else if (format == 1) {
Daniel Veillarddab39b52006-10-16 23:22:10 +00002661 ret = xmlSaveFormatFile(output ? output : "-", doc, 1);
2662 if (ret < 0) {
2663 fprintf(stderr, "failed save to %s\n",
2664 output ? output : "-");
2665 progresult = XMLLINT_ERR_OUT;
2666 }
Daniel Veillard05d987b2003-10-08 11:54:57 +00002667 } else {
Daniel Veillarddab39b52006-10-16 23:22:10 +00002668 FILE *out;
2669 if (output == NULL)
2670 out = stdout;
2671 else {
2672 out = fopen(output,"wb");
2673 }
2674 if (out != NULL) {
2675 if (xmlDocDump(out, doc) < 0)
2676 progresult = XMLLINT_ERR_OUT;
2677
2678 if (output != NULL)
2679 fclose(out);
2680 } else {
2681 fprintf(stderr, "failed to open %s\n", output);
2682 progresult = XMLLINT_ERR_OUT;
2683 }
2684 }
2685 } else {
2686 xmlSaveCtxtPtr ctxt;
2687 int saveOpts = 0;
2688
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002689 if (format == 1)
Daniel Veillarddab39b52006-10-16 23:22:10 +00002690 saveOpts |= XML_SAVE_FORMAT;
Adam Spraggd2e62312010-11-03 15:33:40 +01002691 else if (format == 2)
2692 saveOpts |= XML_SAVE_WSNONSIG;
Daniel Veillard9ccea572010-03-10 15:02:49 +01002693
2694#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
Daniel Veillard9d962642009-08-23 15:31:18 +02002695 if (xmlout)
2696 saveOpts |= XML_SAVE_AS_XML;
Daniel Veillard9ccea572010-03-10 15:02:49 +01002697#endif
Daniel Veillarddab39b52006-10-16 23:22:10 +00002698
2699 if (output == NULL)
2700 ctxt = xmlSaveToFd(1, encoding, saveOpts);
2701 else
2702 ctxt = xmlSaveToFilename(output, encoding, saveOpts);
2703
2704 if (ctxt != NULL) {
2705 if (xmlSaveDoc(ctxt, doc) < 0) {
2706 fprintf(stderr, "failed save to %s\n",
2707 output ? output : "-");
2708 progresult = XMLLINT_ERR_OUT;
2709 }
2710 xmlSaveClose(ctxt);
2711 } else {
William M. Brack8304d872004-06-08 13:29:32 +00002712 progresult = XMLLINT_ERR_OUT;
Daniel Veillard05d987b2003-10-08 11:54:57 +00002713 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002714 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002715 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002716 endTimer("Saving");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002717 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002718#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002719 } else {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002720 FILE *out;
2721 if (output == NULL)
2722 out = stdout;
2723 else {
2724 out = fopen(output,"wb");
2725 }
Daniel Veillard05d987b2003-10-08 11:54:57 +00002726 if (out != NULL) {
2727 xmlDebugDumpDocument(out, doc);
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002728
Daniel Veillard05d987b2003-10-08 11:54:57 +00002729 if (output != NULL)
2730 fclose(out);
2731 } else {
2732 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00002733 progresult = XMLLINT_ERR_OUT;
Daniel Veillard05d987b2003-10-08 11:54:57 +00002734 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002735 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002736#endif
2737 }
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002738#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002739
Daniel Veillard4432df22003-09-28 18:58:27 +00002740#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002741 /*
2742 * A posteriori validation test
2743 */
Daniel Veillard66f68e72003-08-18 16:39:51 +00002744 if ((dtdvalid != NULL) || (dtdvalidfpi != NULL)) {
Daniel Veillardcd429612000-10-11 15:57:05 +00002745 xmlDtdPtr dtd;
2746
Daniel Veillard48b2f892001-02-25 16:11:03 +00002747 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002748 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002749 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00002750 if (dtdvalid != NULL)
Daniel Veillardf1edb102009-08-10 14:43:18 +02002751 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
Daniel Veillard66f68e72003-08-18 16:39:51 +00002752 else
Daniel Veillardf1edb102009-08-10 14:43:18 +02002753 dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL);
Daniel Veillard48b2f892001-02-25 16:11:03 +00002754 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002755 endTimer("Parsing DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002756 }
Daniel Veillardcd429612000-10-11 15:57:05 +00002757 if (dtd == NULL) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00002758 if (dtdvalid != NULL)
2759 xmlGenericError(xmlGenericErrorContext,
2760 "Could not parse DTD %s\n", dtdvalid);
2761 else
2762 xmlGenericError(xmlGenericErrorContext,
2763 "Could not parse DTD %s\n", dtdvalidfpi);
William M. Brack8304d872004-06-08 13:29:32 +00002764 progresult = XMLLINT_ERR_DTD;
Daniel Veillardcd429612000-10-11 15:57:05 +00002765 } else {
Daniel Veillarda37aab82003-06-09 09:10:36 +00002766 xmlValidCtxtPtr cvp;
2767
2768 if ((cvp = xmlNewValidCtxt()) == NULL) {
2769 xmlGenericError(xmlGenericErrorContext,
2770 "Couldn't allocate validation context\n");
2771 exit(-1);
2772 }
2773 cvp->userData = (void *) stderr;
2774 cvp->error = (xmlValidityErrorFunc) fprintf;
2775 cvp->warning = (xmlValidityWarningFunc) fprintf;
2776
Daniel Veillard48b2f892001-02-25 16:11:03 +00002777 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002778 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002779 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002780 if (!xmlValidateDtd(cvp, doc, dtd)) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00002781 if (dtdvalid != NULL)
2782 xmlGenericError(xmlGenericErrorContext,
2783 "Document %s does not validate against %s\n",
2784 filename, dtdvalid);
2785 else
2786 xmlGenericError(xmlGenericErrorContext,
2787 "Document %s does not validate against %s\n",
2788 filename, dtdvalidfpi);
William M. Brack8304d872004-06-08 13:29:32 +00002789 progresult = XMLLINT_ERR_VALID;
Daniel Veillardcd429612000-10-11 15:57:05 +00002790 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002791 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002792 endTimer("Validating against DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002793 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002794 xmlFreeValidCtxt(cvp);
Daniel Veillardcd429612000-10-11 15:57:05 +00002795 xmlFreeDtd(dtd);
2796 }
2797 } else if (postvalid) {
Daniel Veillarda37aab82003-06-09 09:10:36 +00002798 xmlValidCtxtPtr cvp;
2799
2800 if ((cvp = xmlNewValidCtxt()) == NULL) {
2801 xmlGenericError(xmlGenericErrorContext,
2802 "Couldn't allocate validation context\n");
2803 exit(-1);
2804 }
2805
Daniel Veillard48b2f892001-02-25 16:11:03 +00002806 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002807 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002808 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002809 cvp->userData = (void *) stderr;
2810 cvp->error = (xmlValidityErrorFunc) fprintf;
2811 cvp->warning = (xmlValidityWarningFunc) fprintf;
2812 if (!xmlValidateDocument(cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00002813 xmlGenericError(xmlGenericErrorContext,
2814 "Document %s does not validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002815 progresult = XMLLINT_ERR_VALID;
Daniel Veillardcd429612000-10-11 15:57:05 +00002816 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002817 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002818 endTimer("Validating");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002819 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002820 xmlFreeValidCtxt(cvp);
Daniel Veillard4432df22003-09-28 18:58:27 +00002821 }
2822#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardd4501d72005-07-24 14:27:16 +00002823#ifdef LIBXML_SCHEMATRON_ENABLED
2824 if (wxschematron != NULL) {
2825 xmlSchematronValidCtxtPtr ctxt;
2826 int ret;
Daniel Veillardc740a172005-07-31 12:17:24 +00002827 int flag;
Daniel Veillardd4501d72005-07-24 14:27:16 +00002828
2829 if ((timing) && (!repeat)) {
2830 startTimer();
2831 }
2832
2833 if (debug)
2834 flag = XML_SCHEMATRON_OUT_XML;
Daniel Veillardc740a172005-07-31 12:17:24 +00002835 else
2836 flag = XML_SCHEMATRON_OUT_TEXT;
2837 if (noout)
2838 flag |= XML_SCHEMATRON_OUT_QUIET;
Daniel Veillardd4501d72005-07-24 14:27:16 +00002839 ctxt = xmlSchematronNewValidCtxt(wxschematron, flag);
2840#if 0
2841 xmlSchematronSetValidErrors(ctxt,
2842 (xmlSchematronValidityErrorFunc) fprintf,
2843 (xmlSchematronValidityWarningFunc) fprintf,
2844 stderr);
2845#endif
2846 ret = xmlSchematronValidateDoc(ctxt, doc);
2847 if (ret == 0) {
2848 fprintf(stderr, "%s validates\n", filename);
2849 } else if (ret > 0) {
2850 fprintf(stderr, "%s fails to validate\n", filename);
2851 progresult = XMLLINT_ERR_VALID;
2852 } else {
2853 fprintf(stderr, "%s validation generated an internal error\n",
2854 filename);
2855 progresult = XMLLINT_ERR_VALID;
2856 }
2857 xmlSchematronFreeValidCtxt(ctxt);
2858 if ((timing) && (!repeat)) {
2859 endTimer("Validating");
2860 }
2861 }
2862#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00002863#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard4432df22003-09-28 18:58:27 +00002864 if (relaxngschemas != NULL) {
Daniel Veillard71531f32003-02-05 13:19:53 +00002865 xmlRelaxNGValidCtxtPtr ctxt;
2866 int ret;
2867
Daniel Veillard42f12e92003-03-07 18:32:59 +00002868 if ((timing) && (!repeat)) {
2869 startTimer();
2870 }
2871
Daniel Veillard71531f32003-02-05 13:19:53 +00002872 ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
2873 xmlRelaxNGSetValidErrors(ctxt,
2874 (xmlRelaxNGValidityErrorFunc) fprintf,
2875 (xmlRelaxNGValidityWarningFunc) fprintf,
2876 stderr);
2877 ret = xmlRelaxNGValidateDoc(ctxt, doc);
2878 if (ret == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002879 fprintf(stderr, "%s validates\n", filename);
Daniel Veillard71531f32003-02-05 13:19:53 +00002880 } else if (ret > 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002881 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002882 progresult = XMLLINT_ERR_VALID;
Daniel Veillard71531f32003-02-05 13:19:53 +00002883 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002884 fprintf(stderr, "%s validation generated an internal error\n",
Daniel Veillard71531f32003-02-05 13:19:53 +00002885 filename);
William M. Brack8304d872004-06-08 13:29:32 +00002886 progresult = XMLLINT_ERR_VALID;
Daniel Veillard71531f32003-02-05 13:19:53 +00002887 }
2888 xmlRelaxNGFreeValidCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00002889 if ((timing) && (!repeat)) {
2890 endTimer("Validating");
2891 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002892 } else if (wxschemas != NULL) {
2893 xmlSchemaValidCtxtPtr ctxt;
2894 int ret;
2895
2896 if ((timing) && (!repeat)) {
2897 startTimer();
2898 }
2899
2900 ctxt = xmlSchemaNewValidCtxt(wxschemas);
2901 xmlSchemaSetValidErrors(ctxt,
2902 (xmlSchemaValidityErrorFunc) fprintf,
2903 (xmlSchemaValidityWarningFunc) fprintf,
2904 stderr);
2905 ret = xmlSchemaValidateDoc(ctxt, doc);
2906 if (ret == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002907 fprintf(stderr, "%s validates\n", filename);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002908 } else if (ret > 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002909 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002910 progresult = XMLLINT_ERR_VALID;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002911 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002912 fprintf(stderr, "%s validation generated an internal error\n",
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002913 filename);
William M. Brack8304d872004-06-08 13:29:32 +00002914 progresult = XMLLINT_ERR_VALID;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002915 }
2916 xmlSchemaFreeValidCtxt(ctxt);
2917 if ((timing) && (!repeat)) {
2918 endTimer("Validating");
2919 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002920 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002921#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002922
2923#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillard6b099012008-11-06 13:47:39 +00002924#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002925 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00002926 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002927#endif
Daniel Veillard6b099012008-11-06 13:47:39 +00002928#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002929
2930 /*
2931 * free it.
2932 */
Daniel Veillard48b2f892001-02-25 16:11:03 +00002933 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002934 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002935 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002936 xmlFreeDoc(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +00002937 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002938 endTimer("Freeing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002939 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002940}
2941
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002942/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +02002943 * *
2944 * Usage and Main *
2945 * *
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002946 ************************************************************************/
2947
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002948static void showVersion(const char *name) {
2949 fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
2950 fprintf(stderr, " compiled with: ");
Daniel Veillard602434d2005-09-12 09:20:31 +00002951 if (xmlHasFeature(XML_WITH_THREAD)) fprintf(stderr, "Threads ");
2952 if (xmlHasFeature(XML_WITH_TREE)) fprintf(stderr, "Tree ");
2953 if (xmlHasFeature(XML_WITH_OUTPUT)) fprintf(stderr, "Output ");
2954 if (xmlHasFeature(XML_WITH_PUSH)) fprintf(stderr, "Push ");
2955 if (xmlHasFeature(XML_WITH_READER)) fprintf(stderr, "Reader ");
2956 if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(stderr, "Patterns ");
2957 if (xmlHasFeature(XML_WITH_WRITER)) fprintf(stderr, "Writer ");
2958 if (xmlHasFeature(XML_WITH_SAX1)) fprintf(stderr, "SAXv1 ");
Daniel Veillardf1edb102009-08-10 14:43:18 +02002959 if (xmlHasFeature(XML_WITH_FTP)) fprintf(stderr, "FTP ");
2960 if (xmlHasFeature(XML_WITH_HTTP)) fprintf(stderr, "HTTP ");
Daniel Veillard602434d2005-09-12 09:20:31 +00002961 if (xmlHasFeature(XML_WITH_VALID)) fprintf(stderr, "DTDValid ");
Daniel Veillardf1edb102009-08-10 14:43:18 +02002962 if (xmlHasFeature(XML_WITH_HTML)) fprintf(stderr, "HTML ");
2963 if (xmlHasFeature(XML_WITH_LEGACY)) fprintf(stderr, "Legacy ");
2964 if (xmlHasFeature(XML_WITH_C14N)) fprintf(stderr, "C14N ");
2965 if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(stderr, "Catalog ");
2966 if (xmlHasFeature(XML_WITH_XPATH)) fprintf(stderr, "XPath ");
2967 if (xmlHasFeature(XML_WITH_XPTR)) fprintf(stderr, "XPointer ");
2968 if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(stderr, "XInclude ");
2969 if (xmlHasFeature(XML_WITH_ICONV)) fprintf(stderr, "Iconv ");
2970 if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(stderr, "ISO8859X ");
2971 if (xmlHasFeature(XML_WITH_UNICODE)) fprintf(stderr, "Unicode ");
2972 if (xmlHasFeature(XML_WITH_REGEXP)) fprintf(stderr, "Regexps ");
2973 if (xmlHasFeature(XML_WITH_AUTOMATA)) fprintf(stderr, "Automata ");
2974 if (xmlHasFeature(XML_WITH_EXPR)) fprintf(stderr, "Expr ");
2975 if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(stderr, "Schemas ");
2976 if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(stderr, "Schematron ");
2977 if (xmlHasFeature(XML_WITH_MODULES)) fprintf(stderr, "Modules ");
2978 if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(stderr, "Debug ");
2979 if (xmlHasFeature(XML_WITH_DEBUG_MEM)) fprintf(stderr, "MemDebug ");
2980 if (xmlHasFeature(XML_WITH_DEBUG_RUN)) fprintf(stderr, "RunDebug ");
Daniel Veillard75acfee2006-07-13 06:29:56 +00002981 if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(stderr, "Zlib ");
Anders F Bjorklundeae52612011-09-18 16:59:13 +02002982 if (xmlHasFeature(XML_WITH_LZMA)) fprintf(stderr, "Lzma ");
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002983 fprintf(stderr, "\n");
2984}
2985
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002986static void usage(const char *name) {
2987 printf("Usage : %s [options] XMLfiles ...\n", name);
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002988#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002989 printf("\tParse the XML files and output the result of the parsing\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002990#else
2991 printf("\tParse the XML files\n");
2992#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002993 printf("\t--version : display the version of the XML library used\n");
2994#ifdef LIBXML_DEBUG_ENABLED
2995 printf("\t--debug : dump a debug tree of the in-memory document\n");
2996 printf("\t--shell : run a navigating shell\n");
2997 printf("\t--debugent : debug the entities defined in the document\n");
Daniel Veillard8326e732003-01-07 00:19:07 +00002998#else
Daniel Veillard81273902003-09-30 00:43:48 +00002999#ifdef LIBXML_READER_ENABLED
Daniel Veillard8326e732003-01-07 00:19:07 +00003000 printf("\t--debug : dump the nodes content when using --stream\n");
Daniel Veillard81273902003-09-30 00:43:48 +00003001#endif /* LIBXML_READER_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003002#endif
Daniel Veillard652327a2003-09-29 18:02:38 +00003003#ifdef LIBXML_TREE_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003004 printf("\t--copy : used to test the internal copy implementation\n");
Daniel Veillard652327a2003-09-29 18:02:38 +00003005#endif /* LIBXML_TREE_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003006 printf("\t--recover : output what was parsable on broken XML documents\n");
Daniel Veillard8915c152008-08-26 13:05:34 +00003007 printf("\t--huge : remove any internal arbitrary parser limits\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003008 printf("\t--noent : substitute entity references by their value\n");
Daniel Veillardc62efc82011-05-16 16:03:50 +08003009 printf("\t--noenc : ignore any encoding specified inside the document\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003010 printf("\t--noout : don't output the result tree\n");
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003011 printf("\t--path 'paths': provide a set of paths for resources\n");
Jan Pokorný9a85d402013-11-29 23:26:25 +01003012 printf("\t--load-trace : print trace of all external entities loaded\n");
Daniel Veillarde8b09e42003-05-13 22:14:13 +00003013 printf("\t--nonet : refuse to fetch DTDs or entities over network\n");
Daniel Veillard8874b942005-08-25 13:19:21 +00003014 printf("\t--nocompact : do not generate compact text nodes\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003015 printf("\t--htmlout : output results as HTML\n");
Daniel Veillard05c13a22001-09-09 08:38:09 +00003016 printf("\t--nowrap : do not put HTML doc wrapper\n");
Daniel Veillard4432df22003-09-28 18:58:27 +00003017#ifdef LIBXML_VALID_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003018 printf("\t--valid : validate the document in addition to std well-formed check\n");
3019 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
3020 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
Daniel Veillard66f68e72003-08-18 16:39:51 +00003021 printf("\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
Daniel Veillard4432df22003-09-28 18:58:27 +00003022#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003023 printf("\t--timing : print some timings\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003024 printf("\t--output file or -o file: save to a given file\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003025 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
3026 printf("\t--insert : ad-hoc test for valid insertions\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003027#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003028#ifdef HAVE_ZLIB_H
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003029 printf("\t--compress : turn on gzip compression of output\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003030#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003031#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003032#ifdef LIBXML_HTML_ENABLED
3033 printf("\t--html : use the HTML parser\n");
Daniel Veillard42fd4122003-11-04 08:47:48 +00003034 printf("\t--xmlout : force to use the XML serializer when using --html\n");
Daniel Veillardf1121c42010-07-26 14:02:42 +02003035 printf("\t--nodefdtd : do not default HTML doctype\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003036#endif
Daniel Veillard73b013f2003-09-30 12:36:01 +00003037#ifdef LIBXML_PUSH_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003038 printf("\t--push : use the push mode of the parser\n");
Daniel Veillard1abd2212012-10-25 15:37:50 +08003039 printf("\t--pushsmall : use the push mode of the parser using tiny increments\n");
Daniel Veillard73b013f2003-09-30 12:36:01 +00003040#endif /* LIBXML_PUSH_ENABLED */
Daniel Richard G5706b6d2012-08-06 11:32:54 +08003041#ifdef HAVE_MMAP
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003042 printf("\t--memory : parse from memory\n");
3043#endif
Daniel Veillard87076042004-05-03 22:54:49 +00003044 printf("\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003045 printf("\t--nowarning : do not emit warnings from parser/validator\n");
3046 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
Daniel Veillarddca8cc72003-09-26 13:53:14 +00003047 printf("\t--nocdata : replace cdata section with text nodes\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003048#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard90493a92001-08-14 14:12:47 +00003049 printf("\t--format : reformat/reindent the input\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003050 printf("\t--encode encoding : output in the given encoding\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003051 printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
Adam Spraggd2e62312010-11-03 15:33:40 +01003052 printf("\t--pretty STYLE : pretty-print in a particular style\n");
3053 printf("\t 0 Do not pretty print\n");
3054 printf("\t 1 Format the XML content, as --format\n");
3055 printf("\t 2 Add whitespace inside tags, preserving content\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003056#endif /* LIBXML_OUTPUT_ENABLED */
Aleksey Sanin83868242009-07-09 10:26:22 +02003057 printf("\t--c14n : save in W3C canonical format v1.0 (with comments)\n");
3058 printf("\t--c14n11 : save in W3C canonical format v1.1 (with comments)\n");
Aleksey Sanin2650df12005-06-06 17:16:50 +00003059 printf("\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n");
Daniel Veillard25048d82004-08-14 22:37:54 +00003060#ifdef LIBXML_C14N_ENABLED
3061#endif /* LIBXML_C14N_ENABLED */
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003062 printf("\t--nsclean : remove redundant namespace declarations\n");
3063 printf("\t--testIO : test user I/O support\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003064#ifdef LIBXML_CATALOG_ENABLED
Daniel Veillardbd9b0e82001-11-26 10:32:08 +00003065 printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
3066 printf("\t otherwise XML Catalogs starting from \n");
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003067 printf("\t %s are activated by default\n", XML_XML_DEFAULT_CATALOG);
Daniel Veillard05c13a22001-09-09 08:38:09 +00003068 printf("\t--nocatalogs: deactivate all catalogs\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003069#endif
3070 printf("\t--auto : generate a small doc on the fly\n");
3071#ifdef LIBXML_XINCLUDE_ENABLED
3072 printf("\t--xinclude : do XInclude processing\n");
Daniel Veillardc14c3892004-08-16 12:34:50 +00003073 printf("\t--noxincludenode : same but do not generate XInclude nodes\n");
Daniel Veillard54bd29b2008-08-26 07:26:55 +00003074 printf("\t--nofixup-base-uris : do not fixup xml:base uris\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003075#endif
Daniel Veillardcbaf3992001-12-31 16:16:02 +00003076 printf("\t--loaddtd : fetch external DTD\n");
Daniel Veillard48da9102001-08-07 01:10:10 +00003077 printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
Daniel Veillard81273902003-09-30 00:43:48 +00003078#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003079 printf("\t--stream : use the streaming interface to process very large files\n");
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003080 printf("\t--walker : create a reader and walk though the resulting doc\n");
Daniel Veillard81273902003-09-30 00:43:48 +00003081#endif /* LIBXML_READER_ENABLED */
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003082#ifdef LIBXML_PATTERN_ENABLED
3083 printf("\t--pattern pattern_value : test the pattern support\n");
3084#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003085 printf("\t--chkregister : verify the node registration code\n");
Daniel Veillardef4d3bc2003-02-07 12:38:22 +00003086#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard71531f32003-02-05 13:19:53 +00003087 printf("\t--relaxng schema : do RelaxNG validation against the schema\n");
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003088 printf("\t--schema schema : do validation against the WXS schema\n");
Daniel Veillard71531f32003-02-05 13:19:53 +00003089#endif
Daniel Veillarde70375c2005-07-30 21:09:12 +00003090#ifdef LIBXML_SCHEMATRON_ENABLED
3091 printf("\t--schematron schema : do validation against a schematron\n");
3092#endif
Daniel Veillard971771e2005-07-09 17:32:57 +00003093#ifdef LIBXML_SAX1_ENABLED
3094 printf("\t--sax1: use the old SAX1 interfaces for processing\n");
3095#endif
3096 printf("\t--sax: do not build a tree but work just at the SAX level\n");
Daniel Veillard7e5c3f42008-07-29 16:12:31 +00003097 printf("\t--oldxml10: use XML-1.0 parsing rules before the 5th edition\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003098#ifdef LIBXML_XPATH_ENABLED
Daniel Veillard113384f2013-03-27 11:43:41 +08003099 printf("\t--xpath expr: evaluate the XPath expression, imply --noout\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003100#endif
Daniel Veillard971771e2005-07-09 17:32:57 +00003101
Daniel Veillarda42f25f2002-01-25 14:15:40 +00003102 printf("\nLibxml project home page: http://xmlsoft.org/\n");
3103 printf("To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003104}
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003105
3106static void registerNode(xmlNodePtr node)
3107{
3108 node->_private = malloc(sizeof(long));
Daniel Veillarde71dce12013-07-11 15:41:22 +08003109 if (node->_private == NULL) {
3110 fprintf(stderr, "Out of memory in xmllint:registerNode()\n");
3111 exit(XMLLINT_ERR_MEM);
3112 }
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003113 *(long*)node->_private = (long) 0x81726354;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003114 nbregister++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003115}
3116
3117static void deregisterNode(xmlNodePtr node)
3118{
3119 assert(node->_private != NULL);
3120 assert(*(long*)node->_private == (long) 0x81726354);
3121 free(node->_private);
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003122 nbregister--;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003123}
3124
Daniel Veillard4a6845d2001-01-03 13:32:39 +00003125int
3126main(int argc, char **argv) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00003127 int i, acount;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003128 int files = 0;
Daniel Veillard845cce42002-01-09 11:51:37 +00003129 int version = 0;
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00003130 const char* indent;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003131
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003132 if (argc <= 1) {
3133 usage(argv[0]);
3134 return(1);
3135 }
Daniel Veillardbe803962000-06-28 23:40:59 +00003136 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003137 for (i = 1; i < argc ; i++) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003138 if (!strcmp(argv[i], "-"))
3139 break;
3140
3141 if (argv[i][0] != '-')
3142 continue;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003143 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
3144 debug++;
Daniel Veillard56ada1d2003-01-07 11:17:25 +00003145 else
3146#ifdef LIBXML_DEBUG_ENABLED
3147 if ((!strcmp(argv[i], "-shell")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003148 (!strcmp(argv[i], "--shell"))) {
3149 shell++;
3150 noout = 1;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003151 } else
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003152#endif
Daniel Veillard652327a2003-09-29 18:02:38 +00003153#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003154 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
3155 copy++;
Daniel Veillard652327a2003-09-29 18:02:38 +00003156 else
3157#endif /* LIBXML_TREE_ENABLED */
3158 if ((!strcmp(argv[i], "-recover")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003159 (!strcmp(argv[i], "--recover"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003160 recovery++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003161 options |= XML_PARSE_RECOVER;
Daniel Veillard8915c152008-08-26 13:05:34 +00003162 } else if ((!strcmp(argv[i], "-huge")) ||
3163 (!strcmp(argv[i], "--huge"))) {
3164 options |= XML_PARSE_HUGE;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003165 } else if ((!strcmp(argv[i], "-noent")) ||
3166 (!strcmp(argv[i], "--noent"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003167 noent++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003168 options |= XML_PARSE_NOENT;
Daniel Veillardc62efc82011-05-16 16:03:50 +08003169 } else if ((!strcmp(argv[i], "-noenc")) ||
3170 (!strcmp(argv[i], "--noenc"))) {
3171 noenc++;
3172 options |= XML_PARSE_IGNORE_ENC;
Daniel Veillarddca8cc72003-09-26 13:53:14 +00003173 } else if ((!strcmp(argv[i], "-nsclean")) ||
3174 (!strcmp(argv[i], "--nsclean"))) {
3175 options |= XML_PARSE_NSCLEAN;
3176 } else if ((!strcmp(argv[i], "-nocdata")) ||
3177 (!strcmp(argv[i], "--nocdata"))) {
3178 options |= XML_PARSE_NOCDATA;
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003179 } else if ((!strcmp(argv[i], "-nodict")) ||
3180 (!strcmp(argv[i], "--nodict"))) {
3181 options |= XML_PARSE_NODICT;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003182 } else if ((!strcmp(argv[i], "-version")) ||
Daniel Veillard845cce42002-01-09 11:51:37 +00003183 (!strcmp(argv[i], "--version"))) {
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00003184 showVersion(argv[0]);
Daniel Veillard845cce42002-01-09 11:51:37 +00003185 version = 1;
3186 } else if ((!strcmp(argv[i], "-noout")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003187 (!strcmp(argv[i], "--noout")))
3188 noout++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003189#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003190 else if ((!strcmp(argv[i], "-o")) ||
3191 (!strcmp(argv[i], "-output")) ||
3192 (!strcmp(argv[i], "--output"))) {
3193 i++;
Daniel Veillard6e4f1c02002-04-09 09:55:20 +00003194 output = argv[i];
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003195 }
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003196#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003197 else if ((!strcmp(argv[i], "-htmlout")) ||
3198 (!strcmp(argv[i], "--htmlout")))
3199 htmlout++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003200 else if ((!strcmp(argv[i], "-nowrap")) ||
3201 (!strcmp(argv[i], "--nowrap")))
3202 nowrap++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003203#ifdef LIBXML_HTML_ENABLED
3204 else if ((!strcmp(argv[i], "-html")) ||
3205 (!strcmp(argv[i], "--html"))) {
3206 html++;
3207 }
Daniel Veillard42fd4122003-11-04 08:47:48 +00003208 else if ((!strcmp(argv[i], "-xmlout")) ||
3209 (!strcmp(argv[i], "--xmlout"))) {
3210 xmlout++;
Daniel Veillardf1121c42010-07-26 14:02:42 +02003211 } else if ((!strcmp(argv[i], "-nodefdtd")) ||
3212 (!strcmp(argv[i], "--nodefdtd"))) {
3213 nodefdtd++;
3214 options |= HTML_PARSE_NODEFDTD;
Daniel Veillard42fd4122003-11-04 08:47:48 +00003215 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003216#endif /* LIBXML_HTML_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003217 else if ((!strcmp(argv[i], "-loaddtd")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003218 (!strcmp(argv[i], "--loaddtd"))) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003219 loaddtd++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003220 options |= XML_PARSE_DTDLOAD;
3221 } else if ((!strcmp(argv[i], "-dtdattr")) ||
Daniel Veillard48da9102001-08-07 01:10:10 +00003222 (!strcmp(argv[i], "--dtdattr"))) {
3223 loaddtd++;
3224 dtdattrs++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003225 options |= XML_PARSE_DTDATTR;
Daniel Veillard4432df22003-09-28 18:58:27 +00003226 }
3227#ifdef LIBXML_VALID_ENABLED
3228 else if ((!strcmp(argv[i], "-valid")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003229 (!strcmp(argv[i], "--valid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003230 valid++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003231 options |= XML_PARSE_DTDVALID;
3232 } else if ((!strcmp(argv[i], "-postvalid")) ||
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003233 (!strcmp(argv[i], "--postvalid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003234 postvalid++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003235 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003236 options |= XML_PARSE_DTDLOAD;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003237 } else if ((!strcmp(argv[i], "-dtdvalid")) ||
Daniel Veillardcd429612000-10-11 15:57:05 +00003238 (!strcmp(argv[i], "--dtdvalid"))) {
3239 i++;
3240 dtdvalid = argv[i];
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003241 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003242 options |= XML_PARSE_DTDLOAD;
Daniel Veillard66f68e72003-08-18 16:39:51 +00003243 } else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3244 (!strcmp(argv[i], "--dtdvalidfpi"))) {
3245 i++;
3246 dtdvalidfpi = argv[i];
3247 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003248 options |= XML_PARSE_DTDLOAD;
Daniel Veillardcd429612000-10-11 15:57:05 +00003249 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003250#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard29e43992001-12-13 22:21:58 +00003251 else if ((!strcmp(argv[i], "-dropdtd")) ||
3252 (!strcmp(argv[i], "--dropdtd")))
3253 dropdtd++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003254 else if ((!strcmp(argv[i], "-insert")) ||
3255 (!strcmp(argv[i], "--insert")))
3256 insert++;
Daniel Veillard48b2f892001-02-25 16:11:03 +00003257 else if ((!strcmp(argv[i], "-timing")) ||
3258 (!strcmp(argv[i], "--timing")))
3259 timing++;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00003260 else if ((!strcmp(argv[i], "-auto")) ||
3261 (!strcmp(argv[i], "--auto")))
3262 generate++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003263 else if ((!strcmp(argv[i], "-repeat")) ||
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00003264 (!strcmp(argv[i], "--repeat"))) {
3265 if (repeat)
3266 repeat *= 10;
3267 else
3268 repeat = 100;
Daniel Veillard73b013f2003-09-30 12:36:01 +00003269 }
3270#ifdef LIBXML_PUSH_ENABLED
3271 else if ((!strcmp(argv[i], "-push")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003272 (!strcmp(argv[i], "--push")))
3273 push++;
Daniel Veillard1abd2212012-10-25 15:37:50 +08003274 else if ((!strcmp(argv[i], "-pushsmall")) ||
3275 (!strcmp(argv[i], "--pushsmall"))) {
3276 push++;
3277 pushsize = 10;
3278 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00003279#endif /* LIBXML_PUSH_ENABLED */
Daniel Richard G5706b6d2012-08-06 11:32:54 +08003280#ifdef HAVE_MMAP
Daniel Veillard46e370e2000-07-21 20:32:03 +00003281 else if ((!strcmp(argv[i], "-memory")) ||
3282 (!strcmp(argv[i], "--memory")))
3283 memory++;
3284#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +00003285 else if ((!strcmp(argv[i], "-testIO")) ||
3286 (!strcmp(argv[i], "--testIO")))
3287 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003288#ifdef LIBXML_XINCLUDE_ENABLED
3289 else if ((!strcmp(argv[i], "-xinclude")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003290 (!strcmp(argv[i], "--xinclude"))) {
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003291 xinclude++;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003292 options |= XML_PARSE_XINCLUDE;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003293 }
Daniel Veillardc14c3892004-08-16 12:34:50 +00003294 else if ((!strcmp(argv[i], "-noxincludenode")) ||
3295 (!strcmp(argv[i], "--noxincludenode"))) {
3296 xinclude++;
3297 options |= XML_PARSE_XINCLUDE;
3298 options |= XML_PARSE_NOXINCNODE;
3299 }
Daniel Veillard54bd29b2008-08-26 07:26:55 +00003300 else if ((!strcmp(argv[i], "-nofixup-base-uris")) ||
3301 (!strcmp(argv[i], "--nofixup-base-uris"))) {
3302 xinclude++;
3303 options |= XML_PARSE_XINCLUDE;
3304 options |= XML_PARSE_NOBASEFIX;
3305 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003306#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003307#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003308#ifdef HAVE_ZLIB_H
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003309 else if ((!strcmp(argv[i], "-compress")) ||
3310 (!strcmp(argv[i], "--compress"))) {
3311 compress++;
3312 xmlSetCompressMode(9);
3313 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003314#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003315#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003316 else if ((!strcmp(argv[i], "-nowarning")) ||
3317 (!strcmp(argv[i], "--nowarning"))) {
3318 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003319 xmlPedanticParserDefault(0);
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003320 options |= XML_PARSE_NOWARNING;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003321 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003322 else if ((!strcmp(argv[i], "-pedantic")) ||
3323 (!strcmp(argv[i], "--pedantic"))) {
3324 xmlGetWarningsDefaultValue = 1;
3325 xmlPedanticParserDefault(1);
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003326 options |= XML_PARSE_PEDANTIC;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003327 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00003328#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003329 else if ((!strcmp(argv[i], "-debugent")) ||
3330 (!strcmp(argv[i], "--debugent"))) {
3331 debugent++;
3332 xmlParserDebugEntities = 1;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003333 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00003334#endif
Daniel Veillard25048d82004-08-14 22:37:54 +00003335#ifdef LIBXML_C14N_ENABLED
3336 else if ((!strcmp(argv[i], "-c14n")) ||
3337 (!strcmp(argv[i], "--c14n"))) {
3338 canonical++;
3339 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003340 }
Aleksey Sanin83868242009-07-09 10:26:22 +02003341 else if ((!strcmp(argv[i], "-c14n11")) ||
3342 (!strcmp(argv[i], "--c14n11"))) {
3343 canonical_11++;
3344 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003345 }
Aleksey Sanin2650df12005-06-06 17:16:50 +00003346 else if ((!strcmp(argv[i], "-exc-c14n")) ||
3347 (!strcmp(argv[i], "--exc-c14n"))) {
3348 exc_canonical++;
3349 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003350 }
Daniel Veillard25048d82004-08-14 22:37:54 +00003351#endif
Daniel Veillard81418e32001-05-22 15:08:55 +00003352#ifdef LIBXML_CATALOG_ENABLED
3353 else if ((!strcmp(argv[i], "-catalogs")) ||
3354 (!strcmp(argv[i], "--catalogs"))) {
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003355 catalogs++;
3356 } else if ((!strcmp(argv[i], "-nocatalogs")) ||
3357 (!strcmp(argv[i], "--nocatalogs"))) {
3358 nocatalogs++;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003359 }
Daniel Veillard81418e32001-05-22 15:08:55 +00003360#endif
Daniel Veillardbe803962000-06-28 23:40:59 +00003361 else if ((!strcmp(argv[i], "-encode")) ||
3362 (!strcmp(argv[i], "--encode"))) {
3363 i++;
3364 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003365 /*
3366 * OK it's for testing purposes
3367 */
3368 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +00003369 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003370 else if ((!strcmp(argv[i], "-noblanks")) ||
3371 (!strcmp(argv[i], "--noblanks"))) {
Daniel Veillardf933c892012-09-07 19:32:12 +08003372 noblanks++;
3373 xmlKeepBlanksDefault(0);
3374 options |= XML_PARSE_NOBLANKS;
Daniel Veillard90493a92001-08-14 14:12:47 +00003375 }
Daniel Veillard87076042004-05-03 22:54:49 +00003376 else if ((!strcmp(argv[i], "-maxmem")) ||
3377 (!strcmp(argv[i], "--maxmem"))) {
3378 i++;
3379 if (sscanf(argv[i], "%d", &maxmem) == 1) {
3380 xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc,
3381 myStrdupFunc);
3382 } else {
3383 maxmem = 0;
3384 }
3385 }
Daniel Veillard90493a92001-08-14 14:12:47 +00003386 else if ((!strcmp(argv[i], "-format")) ||
3387 (!strcmp(argv[i], "--format"))) {
3388 noblanks++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003389#ifdef LIBXML_OUTPUT_ENABLED
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01003390 format = 1;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003391#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard90493a92001-08-14 14:12:47 +00003392 xmlKeepBlanksDefault(0);
Daniel Veillard7704fb12003-01-03 16:19:51 +00003393 }
Adam Spraggd2e62312010-11-03 15:33:40 +01003394 else if ((!strcmp(argv[i], "-pretty")) ||
3395 (!strcmp(argv[i], "--pretty"))) {
3396 i++;
3397#ifdef LIBXML_OUTPUT_ENABLED
Tim Galeckas2205ff42013-08-29 16:44:33 +08003398 if (argv[i] != NULL) {
3399 format = atoi(argv[i]);
3400 if (format == 1) {
3401 noblanks++;
3402 xmlKeepBlanksDefault(0);
3403 }
3404 }
Brandon Slack0c7109c2012-05-11 10:50:59 +08003405#endif /* LIBXML_OUTPUT_ENABLED */
Adam Spraggd2e62312010-11-03 15:33:40 +01003406 }
Daniel Veillard81273902003-09-30 00:43:48 +00003407#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003408 else if ((!strcmp(argv[i], "-stream")) ||
3409 (!strcmp(argv[i], "--stream"))) {
3410 stream++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003411 }
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003412 else if ((!strcmp(argv[i], "-walker")) ||
3413 (!strcmp(argv[i], "--walker"))) {
3414 walker++;
3415 noout++;
3416 }
Daniel Veillard81273902003-09-30 00:43:48 +00003417#endif /* LIBXML_READER_ENABLED */
3418#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +00003419 else if ((!strcmp(argv[i], "-sax1")) ||
3420 (!strcmp(argv[i], "--sax1"))) {
Daniel Veillard023d0ba2009-07-29 11:34:50 +02003421 sax1++;
3422 options |= XML_PARSE_SAX1;
Daniel Veillard07cb8222003-09-10 10:51:05 +00003423 }
Daniel Veillard81273902003-09-30 00:43:48 +00003424#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003425 else if ((!strcmp(argv[i], "-sax")) ||
3426 (!strcmp(argv[i], "--sax"))) {
Daniel Veillard023d0ba2009-07-29 11:34:50 +02003427 sax++;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003428 }
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003429 else if ((!strcmp(argv[i], "-chkregister")) ||
3430 (!strcmp(argv[i], "--chkregister"))) {
Daniel Veillard023d0ba2009-07-29 11:34:50 +02003431 chkregister++;
Daniel Veillard71531f32003-02-05 13:19:53 +00003432#ifdef LIBXML_SCHEMAS_ENABLED
3433 } else if ((!strcmp(argv[i], "-relaxng")) ||
3434 (!strcmp(argv[i], "--relaxng"))) {
3435 i++;
3436 relaxng = argv[i];
3437 noent++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003438 options |= XML_PARSE_NOENT;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003439 } else if ((!strcmp(argv[i], "-schema")) ||
3440 (!strcmp(argv[i], "--schema"))) {
3441 i++;
3442 schema = argv[i];
3443 noent++;
Daniel Veillard71531f32003-02-05 13:19:53 +00003444#endif
Daniel Veillardd4501d72005-07-24 14:27:16 +00003445#ifdef LIBXML_SCHEMATRON_ENABLED
3446 } else if ((!strcmp(argv[i], "-schematron")) ||
3447 (!strcmp(argv[i], "--schematron"))) {
3448 i++;
3449 schematron = argv[i];
3450 noent++;
3451#endif
Daniel Veillarde8b09e42003-05-13 22:14:13 +00003452 } else if ((!strcmp(argv[i], "-nonet")) ||
3453 (!strcmp(argv[i], "--nonet"))) {
Daniel Veillard61b93382003-11-03 14:28:31 +00003454 options |= XML_PARSE_NONET;
Daniel Veillard968d6432006-04-25 16:17:53 +00003455 xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
Daniel Veillard8874b942005-08-25 13:19:21 +00003456 } else if ((!strcmp(argv[i], "-nocompact")) ||
3457 (!strcmp(argv[i], "--nocompact"))) {
3458 options &= ~XML_PARSE_COMPACT;
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003459 } else if ((!strcmp(argv[i], "-load-trace")) ||
3460 (!strcmp(argv[i], "--load-trace"))) {
3461 load_trace++;
3462 } else if ((!strcmp(argv[i], "-path")) ||
3463 (!strcmp(argv[i], "--path"))) {
3464 i++;
3465 parsePath(BAD_CAST argv[i]);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003466#ifdef LIBXML_PATTERN_ENABLED
3467 } else if ((!strcmp(argv[i], "-pattern")) ||
3468 (!strcmp(argv[i], "--pattern"))) {
3469 i++;
3470 pattern = argv[i];
3471#endif
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003472#ifdef LIBXML_XPATH_ENABLED
3473 } else if ((!strcmp(argv[i], "-xpath")) ||
3474 (!strcmp(argv[i], "--xpath"))) {
3475 i++;
3476 noout++;
3477 xpathquery = argv[i];
3478#endif
Daniel Veillard7e5c3f42008-07-29 16:12:31 +00003479 } else if ((!strcmp(argv[i], "-oldxml10")) ||
3480 (!strcmp(argv[i], "--oldxml10"))) {
3481 oldxml10++;
3482 options |= XML_PARSE_OLD10;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003483 } else {
3484 fprintf(stderr, "Unknown option %s\n", argv[i]);
3485 usage(argv[0]);
3486 return(1);
3487 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003488 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003489
3490#ifdef LIBXML_CATALOG_ENABLED
3491 if (nocatalogs == 0) {
3492 if (catalogs) {
3493 const char *catal;
3494
3495 catal = getenv("SGML_CATALOG_FILES");
Daniel Veillard6c5f9d12001-08-25 13:33:14 +00003496 if (catal != NULL) {
3497 xmlLoadCatalogs(catal);
3498 } else {
3499 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
3500 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003501 }
3502 }
3503#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003504
Daniel Veillard81273902003-09-30 00:43:48 +00003505#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +00003506 if (sax1)
3507 xmlSAXDefaultVersion(1);
3508 else
3509 xmlSAXDefaultVersion(2);
Daniel Veillard81273902003-09-30 00:43:48 +00003510#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillard07cb8222003-09-10 10:51:05 +00003511
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003512 if (chkregister) {
3513 xmlRegisterNodeDefault(registerNode);
3514 xmlDeregisterNodeDefault(deregisterNode);
3515 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02003516
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00003517 indent = getenv("XMLLINT_INDENT");
3518 if(indent != NULL) {
3519 xmlTreeIndentString = indent;
3520 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02003521
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003522
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003523 defaultEntityLoader = xmlGetExternalEntityLoader();
3524 xmlSetExternalEntityLoader(xmllintExternalEntityLoader);
3525
Daniel Veillardd9bad132001-07-23 19:39:43 +00003526 xmlLineNumbersDefault(1);
Daniel Veillard48da9102001-08-07 01:10:10 +00003527 if (loaddtd != 0)
3528 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
3529 if (dtdattrs)
3530 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003531 if (noent != 0) xmlSubstituteEntitiesDefault(1);
Daniel Veillard4432df22003-09-28 18:58:27 +00003532#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003533 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
Daniel Veillard4432df22003-09-28 18:58:27 +00003534#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003535 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003536 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003537 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003538 xmlGenericError(xmlGenericErrorContext,
3539 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
3540 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003541 "<html><head><title>%s output</title></head>\n",
3542 argv[0]);
Daniel Veillardf1edb102009-08-10 14:43:18 +02003543 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003544 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
3545 argv[0]);
3546 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003547
Daniel Veillardd4501d72005-07-24 14:27:16 +00003548#ifdef LIBXML_SCHEMATRON_ENABLED
3549 if ((schematron != NULL) && (sax == 0)
3550#ifdef LIBXML_READER_ENABLED
3551 && (stream == 0)
3552#endif /* LIBXML_READER_ENABLED */
3553 ) {
3554 xmlSchematronParserCtxtPtr ctxt;
3555
3556 /* forces loading the DTDs */
Daniel Veillardf1edb102009-08-10 14:43:18 +02003557 xmlLoadExtDtdDefaultValue |= 1;
Daniel Veillardd4501d72005-07-24 14:27:16 +00003558 options |= XML_PARSE_DTDLOAD;
3559 if (timing) {
3560 startTimer();
3561 }
3562 ctxt = xmlSchematronNewParserCtxt(schematron);
3563#if 0
3564 xmlSchematronSetParserErrors(ctxt,
3565 (xmlSchematronValidityErrorFunc) fprintf,
3566 (xmlSchematronValidityWarningFunc) fprintf,
3567 stderr);
3568#endif
3569 wxschematron = xmlSchematronParse(ctxt);
3570 if (wxschematron == NULL) {
3571 xmlGenericError(xmlGenericErrorContext,
3572 "Schematron schema %s failed to compile\n", schematron);
3573 progresult = XMLLINT_ERR_SCHEMACOMP;
3574 schematron = NULL;
3575 }
3576 xmlSchematronFreeParserCtxt(ctxt);
3577 if (timing) {
3578 endTimer("Compiling the schemas");
3579 }
3580 }
3581#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00003582#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003583 if ((relaxng != NULL) && (sax == 0)
Daniel Veillard81273902003-09-30 00:43:48 +00003584#ifdef LIBXML_READER_ENABLED
3585 && (stream == 0)
3586#endif /* LIBXML_READER_ENABLED */
3587 ) {
Daniel Veillard71531f32003-02-05 13:19:53 +00003588 xmlRelaxNGParserCtxtPtr ctxt;
3589
Daniel Veillardce192eb2003-04-16 15:58:05 +00003590 /* forces loading the DTDs */
Daniel Veillardf1edb102009-08-10 14:43:18 +02003591 xmlLoadExtDtdDefaultValue |= 1;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003592 options |= XML_PARSE_DTDLOAD;
Daniel Veillard42f12e92003-03-07 18:32:59 +00003593 if (timing) {
3594 startTimer();
3595 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003596 ctxt = xmlRelaxNGNewParserCtxt(relaxng);
3597 xmlRelaxNGSetParserErrors(ctxt,
3598 (xmlRelaxNGValidityErrorFunc) fprintf,
3599 (xmlRelaxNGValidityWarningFunc) fprintf,
3600 stderr);
3601 relaxngschemas = xmlRelaxNGParse(ctxt);
Daniel Veillardce192eb2003-04-16 15:58:05 +00003602 if (relaxngschemas == NULL) {
3603 xmlGenericError(xmlGenericErrorContext,
3604 "Relax-NG schema %s failed to compile\n", relaxng);
William M. Brack8304d872004-06-08 13:29:32 +00003605 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillardce192eb2003-04-16 15:58:05 +00003606 relaxng = NULL;
3607 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003608 xmlRelaxNGFreeParserCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00003609 if (timing) {
3610 endTimer("Compiling the schemas");
3611 }
Daniel Veillardebe25d42004-03-25 09:35:49 +00003612 } else if ((schema != NULL)
3613#ifdef LIBXML_READER_ENABLED
Daniel Veillardf10ae122005-07-10 19:03:16 +00003614 && (stream == 0)
Daniel Veillardebe25d42004-03-25 09:35:49 +00003615#endif
3616 ) {
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003617 xmlSchemaParserCtxtPtr ctxt;
3618
3619 if (timing) {
3620 startTimer();
3621 }
3622 ctxt = xmlSchemaNewParserCtxt(schema);
3623 xmlSchemaSetParserErrors(ctxt,
3624 (xmlSchemaValidityErrorFunc) fprintf,
3625 (xmlSchemaValidityWarningFunc) fprintf,
3626 stderr);
3627 wxschemas = xmlSchemaParse(ctxt);
3628 if (wxschemas == NULL) {
3629 xmlGenericError(xmlGenericErrorContext,
3630 "WXS schema %s failed to compile\n", schema);
William M. Brack8304d872004-06-08 13:29:32 +00003631 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003632 schema = NULL;
3633 }
3634 xmlSchemaFreeParserCtxt(ctxt);
3635 if (timing) {
3636 endTimer("Compiling the schemas");
3637 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003638 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003639#endif /* LIBXML_SCHEMAS_ENABLED */
3640#ifdef LIBXML_PATTERN_ENABLED
Daniel Veillard39e5c892005-07-03 22:48:50 +00003641 if ((pattern != NULL)
Daniel Veillardc9352532005-07-04 14:25:34 +00003642#ifdef LIBXML_READER_ENABLED
Daniel Veillard39e5c892005-07-03 22:48:50 +00003643 && (walker == 0)
3644#endif
3645 ) {
Daniel Veillardffa7b7e2003-12-05 16:10:21 +00003646 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003647 if (patternc == NULL) {
3648 xmlGenericError(xmlGenericErrorContext,
3649 "Pattern %s failed to compile\n", pattern);
William M. Brack8304d872004-06-08 13:29:32 +00003650 progresult = XMLLINT_ERR_SCHEMAPAT;
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003651 pattern = NULL;
3652 }
3653 }
3654#endif /* LIBXML_PATTERN_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003655 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +00003656 if ((!strcmp(argv[i], "-encode")) ||
3657 (!strcmp(argv[i], "--encode"))) {
3658 i++;
3659 continue;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003660 } else if ((!strcmp(argv[i], "-o")) ||
3661 (!strcmp(argv[i], "-output")) ||
3662 (!strcmp(argv[i], "--output"))) {
3663 i++;
3664 continue;
Daniel Veillardbe803962000-06-28 23:40:59 +00003665 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003666#ifdef LIBXML_VALID_ENABLED
Daniel Veillardcd429612000-10-11 15:57:05 +00003667 if ((!strcmp(argv[i], "-dtdvalid")) ||
3668 (!strcmp(argv[i], "--dtdvalid"))) {
3669 i++;
3670 continue;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003671 }
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003672 if ((!strcmp(argv[i], "-path")) ||
3673 (!strcmp(argv[i], "--path"))) {
3674 i++;
3675 continue;
Daniel Veillardcd429612000-10-11 15:57:05 +00003676 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00003677 if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3678 (!strcmp(argv[i], "--dtdvalidfpi"))) {
3679 i++;
3680 continue;
3681 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003682#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard71531f32003-02-05 13:19:53 +00003683 if ((!strcmp(argv[i], "-relaxng")) ||
3684 (!strcmp(argv[i], "--relaxng"))) {
3685 i++;
3686 continue;
3687 }
Daniel Veillard87076042004-05-03 22:54:49 +00003688 if ((!strcmp(argv[i], "-maxmem")) ||
3689 (!strcmp(argv[i], "--maxmem"))) {
3690 i++;
3691 continue;
3692 }
Adam Spraggd2e62312010-11-03 15:33:40 +01003693 if ((!strcmp(argv[i], "-pretty")) ||
3694 (!strcmp(argv[i], "--pretty"))) {
3695 i++;
3696 continue;
3697 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003698 if ((!strcmp(argv[i], "-schema")) ||
3699 (!strcmp(argv[i], "--schema"))) {
3700 i++;
3701 continue;
3702 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00003703 if ((!strcmp(argv[i], "-schematron")) ||
3704 (!strcmp(argv[i], "--schematron"))) {
3705 i++;
3706 continue;
3707 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003708#ifdef LIBXML_PATTERN_ENABLED
3709 if ((!strcmp(argv[i], "-pattern")) ||
3710 (!strcmp(argv[i], "--pattern"))) {
3711 i++;
3712 continue;
3713 }
3714#endif
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003715#ifdef LIBXML_XPATH_ENABLED
3716 if ((!strcmp(argv[i], "-xpath")) ||
3717 (!strcmp(argv[i], "--xpath"))) {
3718 i++;
3719 continue;
3720 }
3721#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00003722 if ((timing) && (repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00003723 startTimer();
Daniel Veillardcbaf3992001-12-31 16:16:02 +00003724 /* Remember file names. "-" means stdin. <sven@zen.org> */
Daniel Veillard4a6845d2001-01-03 13:32:39 +00003725 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003726 if (repeat) {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003727 xmlParserCtxtPtr ctxt = NULL;
3728
3729 for (acount = 0;acount < repeat;acount++) {
Daniel Veillard81273902003-09-30 00:43:48 +00003730#ifdef LIBXML_READER_ENABLED
Daniel Veillard198c1bf2003-10-20 17:07:41 +00003731 if (stream != 0) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00003732 streamFile(argv[i]);
Daniel Veillard198c1bf2003-10-20 17:07:41 +00003733 } else {
Daniel Veillard81273902003-09-30 00:43:48 +00003734#endif /* LIBXML_READER_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003735 if (sax) {
3736 testSAX(argv[i]);
3737 } else {
3738 if (ctxt == NULL)
3739 ctxt = xmlNewParserCtxt();
3740 parseAndPrintFile(argv[i], ctxt);
3741 }
Daniel Veillard81273902003-09-30 00:43:48 +00003742#ifdef LIBXML_READER_ENABLED
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003743 }
Daniel Veillard81273902003-09-30 00:43:48 +00003744#endif /* LIBXML_READER_ENABLED */
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003745 }
3746 if (ctxt != NULL)
3747 xmlFreeParserCtxt(ctxt);
Daniel Veillard7704fb12003-01-03 16:19:51 +00003748 } else {
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003749 nbregister = 0;
3750
Daniel Veillard81273902003-09-30 00:43:48 +00003751#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003752 if (stream != 0)
3753 streamFile(argv[i]);
3754 else
Daniel Veillard81273902003-09-30 00:43:48 +00003755#endif /* LIBXML_READER_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003756 if (sax) {
3757 testSAX(argv[i]);
3758 } else {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003759 parseAndPrintFile(argv[i], NULL);
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003760 }
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003761
3762 if ((chkregister) && (nbregister != 0)) {
3763 fprintf(stderr, "Registration count off: %d\n", nbregister);
William M. Brack8304d872004-06-08 13:29:32 +00003764 progresult = XMLLINT_ERR_RDREGIS;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003765 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00003766 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003767 files ++;
Daniel Veillarda7866932001-12-04 13:14:44 +00003768 if ((timing) && (repeat)) {
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00003769 endTimer("%d iterations", repeat);
Daniel Veillarda7866932001-12-04 13:14:44 +00003770 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00003771 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003772 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02003773 if (generate)
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003774 parseAndPrintFile(NULL, NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003775 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003776 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003777 }
Daniel Veillard845cce42002-01-09 11:51:37 +00003778 if ((files == 0) && (!generate) && (version == 0)) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003779 usage(argv[0]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003780 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00003781#ifdef LIBXML_SCHEMATRON_ENABLED
3782 if (wxschematron != NULL)
3783 xmlSchematronFree(wxschematron);
3784#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00003785#ifdef LIBXML_SCHEMAS_ENABLED
3786 if (relaxngschemas != NULL)
3787 xmlRelaxNGFree(relaxngschemas);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003788 if (wxschemas != NULL)
3789 xmlSchemaFree(wxschemas);
Daniel Veillard71531f32003-02-05 13:19:53 +00003790 xmlRelaxNGCleanupTypes();
3791#endif
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003792#ifdef LIBXML_PATTERN_ENABLED
3793 if (patternc != NULL)
3794 xmlFreePattern(patternc);
3795#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003796 xmlCleanupParser();
3797 xmlMemoryDump();
3798
Daniel Veillardf7cd4812001-02-23 18:44:52 +00003799 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003800}
Daniel Veillard88a172f2000-08-04 18:23:10 +00003801