blob: 88c4a6b981346910a572088be5f02c7cd75f5e43 [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 Veillarda9cce9c2003-09-29 13:20:24 +0000133static int noblanks = 0;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000134static int noout = 0;
135static int nowrap = 0;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +0000136#ifdef LIBXML_OUTPUT_ENABLED
137static int format = 0;
138static const char *output = NULL;
139static int compress = 0;
Daniel Veillarddab39b52006-10-16 23:22:10 +0000140static int oldout = 0;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +0000141#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard4432df22003-09-28 18:58:27 +0000142#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000143static int valid = 0;
144static int postvalid = 0;
Daniel Veillardcd429612000-10-11 15:57:05 +0000145static char * dtdvalid = NULL;
Daniel Veillard66f68e72003-08-18 16:39:51 +0000146static char * dtdvalidfpi = NULL;
Daniel Veillard4432df22003-09-28 18:58:27 +0000147#endif
Daniel Veillard71531f32003-02-05 13:19:53 +0000148#ifdef LIBXML_SCHEMAS_ENABLED
149static char * relaxng = NULL;
150static xmlRelaxNGPtr relaxngschemas = NULL;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +0000151static char * schema = NULL;
152static xmlSchemaPtr wxschemas = NULL;
Daniel Veillard71531f32003-02-05 13:19:53 +0000153#endif
Daniel Veillard8c6e6532005-09-08 21:39:47 +0000154#ifdef LIBXML_SCHEMATRON_ENABLED
Daniel Veillardd4501d72005-07-24 14:27:16 +0000155static char * schematron = NULL;
156static xmlSchematronPtr wxschematron = NULL;
157#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000158static int repeat = 0;
159static int insert = 0;
Daniel Veillard656ce942004-04-30 23:11:45 +0000160#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000161static int html = 0;
Daniel Veillard42fd4122003-11-04 08:47:48 +0000162static int xmlout = 0;
Daniel Veillard4432df22003-09-28 18:58:27 +0000163#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000164static int htmlout = 0;
Daniel Veillardf1121c42010-07-26 14:02:42 +0200165#if defined(LIBXML_HTML_ENABLED)
166static int nodefdtd = 0;
167#endif
Daniel Veillard73b013f2003-09-30 12:36:01 +0000168#ifdef LIBXML_PUSH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000169static int push = 0;
Daniel Veillard73b013f2003-09-30 12:36:01 +0000170#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillard46e370e2000-07-21 20:32:03 +0000171#ifdef HAVE_SYS_MMAN_H
172static int memory = 0;
173#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +0000174static int testIO = 0;
Daniel Veillardbe803962000-06-28 23:40:59 +0000175static char *encoding = NULL;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000176#ifdef LIBXML_XINCLUDE_ENABLED
177static int xinclude = 0;
178#endif
Daniel Veillard48da9102001-08-07 01:10:10 +0000179static int dtdattrs = 0;
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000180static int loaddtd = 0;
William M. Brack8304d872004-06-08 13:29:32 +0000181static xmllintReturnCode progresult = XMLLINT_RETURN_OK;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000182static int timing = 0;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000183static int generate = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000184static int dropdtd = 0;
Daniel Veillarde2940dd2001-08-22 00:06:49 +0000185#ifdef LIBXML_CATALOG_ENABLED
186static int catalogs = 0;
187static int nocatalogs = 0;
188#endif
Daniel Veillard25048d82004-08-14 22:37:54 +0000189#ifdef LIBXML_C14N_ENABLED
190static int canonical = 0;
Aleksey Sanin83868242009-07-09 10:26:22 +0200191static int canonical_11 = 0;
Aleksey Sanin2650df12005-06-06 17:16:50 +0000192static int exc_canonical = 0;
Daniel Veillard25048d82004-08-14 22:37:54 +0000193#endif
Daniel Veillard81273902003-09-30 00:43:48 +0000194#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +0000195static int stream = 0;
Daniel Veillard7899c5c2003-11-03 12:31:38 +0000196static int walker = 0;
Daniel Veillard81273902003-09-30 00:43:48 +0000197#endif /* LIBXML_READER_ENABLED */
Daniel Veillard8a1b1852003-01-05 22:37:17 +0000198static int chkregister = 0;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +0000199static int nbregister = 0;
Daniel Veillard81273902003-09-30 00:43:48 +0000200#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +0000201static int sax1 = 0;
Daniel Veillard81273902003-09-30 00:43:48 +0000202#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillardb3de70c2003-12-02 22:32:15 +0000203#ifdef LIBXML_PATTERN_ENABLED
204static const char *pattern = NULL;
205static xmlPatternPtr patternc = NULL;
Daniel Veillard2fc6df92005-01-30 18:42:55 +0000206static xmlStreamCtxtPtr patstream = NULL;
Daniel Veillardb3de70c2003-12-02 22:32:15 +0000207#endif
Daniel Veillard1934b0c2009-10-07 10:25:06 +0200208#ifdef LIBXML_XPATH_ENABLED
209static const char *xpathquery = NULL;
210#endif
Daniel Veillard8874b942005-08-25 13:19:21 +0000211static int options = XML_PARSE_COMPACT;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000212static int sax = 0;
Daniel Veillard7e5c3f42008-07-29 16:12:31 +0000213static int oldxml10 = 0;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +0000214
Daniel Veillard87076042004-05-03 22:54:49 +0000215/************************************************************************
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000216 * *
217 * Entity loading control and customization. *
218 * *
219 ************************************************************************/
220#define MAX_PATHS 64
Daniel Veillarded121382007-04-17 12:33:19 +0000221#ifdef _WIN32
222# define PATH_SEPARATOR ';'
223#else
224# define PATH_SEPARATOR ':'
225#endif
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000226static xmlChar *paths[MAX_PATHS + 1];
227static int nbpaths = 0;
228static int load_trace = 0;
229
230static
231void parsePath(const xmlChar *path) {
232 const xmlChar *cur;
233
234 if (path == NULL)
235 return;
236 while (*path != 0) {
237 if (nbpaths >= MAX_PATHS) {
238 fprintf(stderr, "MAX_PATHS reached: too many paths\n");
239 return;
240 }
241 cur = path;
Daniel Veillarded121382007-04-17 12:33:19 +0000242 while ((*cur == ' ') || (*cur == PATH_SEPARATOR))
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000243 cur++;
244 path = cur;
Daniel Veillarded121382007-04-17 12:33:19 +0000245 while ((*cur != 0) && (*cur != ' ') && (*cur != PATH_SEPARATOR))
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000246 cur++;
247 if (cur != path) {
248 paths[nbpaths] = xmlStrndup(path, cur - path);
249 if (paths[nbpaths] != NULL)
250 nbpaths++;
251 path = cur;
252 }
253 }
254}
255
Daniel Veillard24505b02005-07-28 23:49:35 +0000256static xmlExternalEntityLoader defaultEntityLoader = NULL;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000257
Daniel Veillardf1edb102009-08-10 14:43:18 +0200258static xmlParserInputPtr
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000259xmllintExternalEntityLoader(const char *URL, const char *ID,
260 xmlParserCtxtPtr ctxt) {
261 xmlParserInputPtr ret;
262 warningSAXFunc warning = NULL;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000263 errorSAXFunc err = NULL;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000264
265 int i;
266 const char *lastsegment = URL;
267 const char *iter = URL;
268
Daniel Veillard5608b172008-01-11 06:53:15 +0000269 if ((nbpaths > 0) && (iter != NULL)) {
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000270 while (*iter != 0) {
271 if (*iter == '/')
272 lastsegment = iter + 1;
273 iter++;
274 }
275 }
276
277 if ((ctxt != NULL) && (ctxt->sax != NULL)) {
278 warning = ctxt->sax->warning;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000279 err = ctxt->sax->error;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000280 ctxt->sax->warning = NULL;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000281 ctxt->sax->error = NULL;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000282 }
283
284 if (defaultEntityLoader != NULL) {
285 ret = defaultEntityLoader(URL, ID, ctxt);
286 if (ret != NULL) {
287 if (warning != NULL)
288 ctxt->sax->warning = warning;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000289 if (err != NULL)
290 ctxt->sax->error = err;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000291 if (load_trace) {
292 fprintf \
293 (stderr,
294 "Loaded URL=\"%s\" ID=\"%s\"\n",
295 URL ? URL : "(null)",
296 ID ? ID : "(null)");
297 }
298 return(ret);
299 }
300 }
301 for (i = 0;i < nbpaths;i++) {
302 xmlChar *newURL;
303
304 newURL = xmlStrdup((const xmlChar *) paths[i]);
305 newURL = xmlStrcat(newURL, (const xmlChar *) "/");
306 newURL = xmlStrcat(newURL, (const xmlChar *) lastsegment);
307 if (newURL != NULL) {
308 ret = defaultEntityLoader((const char *)newURL, ID, ctxt);
309 if (ret != NULL) {
310 if (warning != NULL)
311 ctxt->sax->warning = warning;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000312 if (err != NULL)
313 ctxt->sax->error = err;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000314 if (load_trace) {
315 fprintf \
Daniel Veillardf1edb102009-08-10 14:43:18 +0200316 (stderr,
317 "Loaded URL=\"%s\" ID=\"%s\"\n",
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000318 newURL,
Daniel Veillardf1edb102009-08-10 14:43:18 +0200319 ID ? ID : "(null)");
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000320 }
321 xmlFree(newURL);
322 return(ret);
323 }
324 xmlFree(newURL);
325 }
326 }
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000327 if (err != NULL)
328 ctxt->sax->error = err;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000329 if (warning != NULL) {
330 ctxt->sax->warning = warning;
331 if (URL != NULL)
332 warning(ctxt, "failed to load external entity \"%s\"\n", URL);
333 else if (ID != NULL)
334 warning(ctxt, "failed to load external entity \"%s\"\n", ID);
335 }
336 return(NULL);
337}
338/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +0200339 * *
Daniel Veillard87076042004-05-03 22:54:49 +0000340 * Memory allocation consumption debugging *
Daniel Veillardf1edb102009-08-10 14:43:18 +0200341 * *
Daniel Veillard87076042004-05-03 22:54:49 +0000342 ************************************************************************/
343
Daniel Veillard3af3b592004-05-05 19:22:30 +0000344static void
345OOM(void)
346{
Daniel Veillard87076042004-05-03 22:54:49 +0000347 fprintf(stderr, "Ran out of memory needs > %d bytes\n", maxmem);
William M. Brack8304d872004-06-08 13:29:32 +0000348 progresult = XMLLINT_ERR_MEM;
Daniel Veillard87076042004-05-03 22:54:49 +0000349}
350
Daniel Veillard3af3b592004-05-05 19:22:30 +0000351static void
352myFreeFunc(void *mem)
353{
Daniel Veillard87076042004-05-03 22:54:49 +0000354 xmlMemFree(mem);
355}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000356static void *
357myMallocFunc(size_t size)
358{
Daniel Veillard87076042004-05-03 22:54:49 +0000359 void *ret;
360
361 ret = xmlMemMalloc(size);
362 if (ret != NULL) {
363 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000364 OOM();
365 xmlMemFree(ret);
366 return (NULL);
367 }
Daniel Veillard87076042004-05-03 22:54:49 +0000368 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000369 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000370}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000371static void *
372myReallocFunc(void *mem, size_t size)
373{
Daniel Veillard87076042004-05-03 22:54:49 +0000374 void *ret;
375
376 ret = xmlMemRealloc(mem, size);
377 if (ret != NULL) {
378 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000379 OOM();
380 xmlMemFree(ret);
381 return (NULL);
382 }
Daniel Veillard87076042004-05-03 22:54:49 +0000383 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000384 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000385}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000386static char *
387myStrdupFunc(const char *str)
388{
Daniel Veillard87076042004-05-03 22:54:49 +0000389 char *ret;
390
391 ret = xmlMemoryStrdup(str);
392 if (ret != NULL) {
393 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000394 OOM();
395 xmlFree(ret);
396 return (NULL);
397 }
Daniel Veillard87076042004-05-03 22:54:49 +0000398 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000399 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000400}
Daniel Veillard87076042004-05-03 22:54:49 +0000401/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +0200402 * *
Daniel Veillard87076042004-05-03 22:54:49 +0000403 * Internal timing routines to remove the necessity to have *
404 * unix-specific function calls. *
Daniel Veillardf1edb102009-08-10 14:43:18 +0200405 * *
Daniel Veillard87076042004-05-03 22:54:49 +0000406 ************************************************************************/
Daniel Veillard01db67c2001-12-18 07:09:59 +0000407
Daniel Veillardf1edb102009-08-10 14:43:18 +0200408#ifndef HAVE_GETTIMEOFDAY
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000409#ifdef HAVE_SYS_TIMEB_H
410#ifdef HAVE_SYS_TIME_H
411#ifdef HAVE_FTIME
412
Daniel Veillard01c13b52002-12-10 15:19:08 +0000413static int
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000414my_gettimeofday(struct timeval *tvp, void *tzp)
415{
416 struct timeb timebuffer;
417
418 ftime(&timebuffer);
419 if (tvp) {
420 tvp->tv_sec = timebuffer.time;
421 tvp->tv_usec = timebuffer.millitm * 1000L;
422 }
423 return (0);
424}
425#define HAVE_GETTIMEOFDAY 1
426#define gettimeofday my_gettimeofday
427
428#endif /* HAVE_FTIME */
429#endif /* HAVE_SYS_TIME_H */
430#endif /* HAVE_SYS_TIMEB_H */
431#endif /* !HAVE_GETTIMEOFDAY */
432
Daniel Veillard01db67c2001-12-18 07:09:59 +0000433#if defined(HAVE_GETTIMEOFDAY)
434static struct timeval begin, end;
435
436/*
437 * startTimer: call where you want to start timing
438 */
439static void
440startTimer(void)
441{
442 gettimeofday(&begin, NULL);
443}
444
445/*
446 * endTimer: call where you want to stop timing and to print out a
447 * message about the timing performed; format is a printf
448 * type argument
449 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000450static void XMLCDECL
Daniel Veillard118aed72002-09-24 14:13:13 +0000451endTimer(const char *fmt, ...)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000452{
453 long msec;
454 va_list ap;
455
456 gettimeofday(&end, NULL);
457 msec = end.tv_sec - begin.tv_sec;
458 msec *= 1000;
459 msec += (end.tv_usec - begin.tv_usec) / 1000;
460
461#ifndef HAVE_STDARG_H
462#error "endTimer required stdarg functions"
463#endif
Daniel Veillard118aed72002-09-24 14:13:13 +0000464 va_start(ap, fmt);
465 vfprintf(stderr, fmt, ap);
Daniel Veillard01db67c2001-12-18 07:09:59 +0000466 va_end(ap);
467
468 fprintf(stderr, " took %ld ms\n", msec);
469}
470#elif defined(HAVE_TIME_H)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000471/*
472 * No gettimeofday function, so we have to make do with calling clock.
473 * This is obviously less accurate, but there's little we can do about
474 * that.
475 */
Daniel Veillard90bc3712002-03-07 15:12:58 +0000476#ifndef CLOCKS_PER_SEC
477#define CLOCKS_PER_SEC 100
478#endif
Daniel Veillard01db67c2001-12-18 07:09:59 +0000479
480static clock_t begin, end;
481static void
482startTimer(void)
483{
484 begin = clock();
485}
Daniel Veillardffa3c742005-07-21 13:24:09 +0000486static void XMLCDECL
Daniel Veillard01db67c2001-12-18 07:09:59 +0000487endTimer(const char *fmt, ...)
488{
489 long msec;
490 va_list ap;
491
492 end = clock();
493 msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
494
495#ifndef HAVE_STDARG_H
496#error "endTimer required stdarg functions"
497#endif
498 va_start(ap, fmt);
499 vfprintf(stderr, fmt, ap);
500 va_end(ap);
501 fprintf(stderr, " took %ld ms\n", msec);
502}
503#else
504
505/*
506 * We don't have a gettimeofday or time.h, so we just don't do timing
507 */
508static void
509startTimer(void)
510{
511 /*
512 * Do nothing
513 */
514}
Daniel Veillardffa3c742005-07-21 13:24:09 +0000515static void XMLCDECL
Daniel Veillard01db67c2001-12-18 07:09:59 +0000516endTimer(char *format, ...)
517{
518 /*
519 * We cannot do anything because we don't have a timing function
520 */
521#ifdef HAVE_STDARG_H
522 va_start(ap, format);
523 vfprintf(stderr, format, ap);
524 va_end(ap);
525 fprintf(stderr, " was not timed\n", msec);
526#else
527 /* We don't have gettimeofday, time or stdarg.h, what crazy world is
528 * this ?!
529 */
530#endif
531}
532#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000533/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +0200534 * *
535 * HTML ouput *
536 * *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000537 ************************************************************************/
Daniel Veillard24505b02005-07-28 23:49:35 +0000538static char buffer[50000];
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000539
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000540static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000541xmlHTMLEncodeSend(void) {
542 char *result;
543
544 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
545 if (result) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000546 xmlGenericError(xmlGenericErrorContext, "%s", result);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000547 xmlFree(result);
548 }
549 buffer[0] = 0;
550}
551
552/**
553 * xmlHTMLPrintFileInfo:
554 * @input: an xmlParserInputPtr input
Daniel Veillardf1edb102009-08-10 14:43:18 +0200555 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000556 * Displays the associated file and line informations for the current input
557 */
558
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000559static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000560xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000561 int len;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000562 xmlGenericError(xmlGenericErrorContext, "<p>");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000563
564 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000565 if (input != NULL) {
566 if (input->filename) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000567 snprintf(&buffer[len], sizeof(buffer) - len, "%s:%d: ", input->filename,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000568 input->line);
569 } else {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000570 snprintf(&buffer[len], sizeof(buffer) - len, "Entity: line %d: ", input->line);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000571 }
572 }
573 xmlHTMLEncodeSend();
574}
575
576/**
577 * xmlHTMLPrintFileContext:
578 * @input: an xmlParserInputPtr input
Daniel Veillardf1edb102009-08-10 14:43:18 +0200579 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000580 * Displays current context within the input content for error tracking
581 */
582
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000583static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000584xmlHTMLPrintFileContext(xmlParserInputPtr input) {
585 const xmlChar *cur, *base;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000586 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000587 int n;
588
589 if (input == NULL) return;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000590 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000591 cur = input->cur;
592 base = input->base;
593 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
594 cur--;
595 }
596 n = 0;
597 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
598 cur--;
599 if ((*cur == '\n') || (*cur == '\r')) cur++;
600 base = cur;
601 n = 0;
602 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000603 len = strlen(buffer);
Daniel Veillardf1edb102009-08-10 14:43:18 +0200604 snprintf(&buffer[len], sizeof(buffer) - len, "%c",
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000605 (unsigned char) *cur++);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000606 n++;
607 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000608 len = strlen(buffer);
609 snprintf(&buffer[len], sizeof(buffer) - len, "\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000610 cur = input->cur;
611 while ((*cur == '\n') || (*cur == '\r'))
612 cur--;
613 n = 0;
614 while ((cur != base) && (n++ < 80)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000615 len = strlen(buffer);
616 snprintf(&buffer[len], sizeof(buffer) - len, " ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000617 base++;
618 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000619 len = strlen(buffer);
620 snprintf(&buffer[len], sizeof(buffer) - len, "^\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000621 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000622 xmlGenericError(xmlGenericErrorContext, "</pre>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000623}
624
625/**
626 * xmlHTMLError:
627 * @ctx: an XML parser context
628 * @msg: the message to display/transmit
629 * @...: extra parameters for the message display
Daniel Veillardf1edb102009-08-10 14:43:18 +0200630 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000631 * Display and format an error messages, gives file, line, position and
632 * extra parameters.
633 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000634static void XMLCDECL
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000635xmlHTMLError(void *ctx, const char *msg, ...)
636{
637 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
638 xmlParserInputPtr input;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000639 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000640 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000641
642 buffer[0] = 0;
643 input = ctxt->input;
644 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000645 input = ctxt->inputTab[ctxt->inputNr - 2];
646 }
Daniel Veillardf1edb102009-08-10 14:43:18 +0200647
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000648 xmlHTMLPrintFileInfo(input);
649
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000650 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000651 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000652 len = strlen(buffer);
653 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000654 va_end(args);
655 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000656 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000657
658 xmlHTMLPrintFileContext(input);
659 xmlHTMLEncodeSend();
660}
661
662/**
663 * xmlHTMLWarning:
664 * @ctx: an XML parser context
665 * @msg: the message to display/transmit
666 * @...: extra parameters for the message display
Daniel Veillardf1edb102009-08-10 14:43:18 +0200667 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000668 * Display and format a warning messages, gives file, line, position and
669 * extra parameters.
670 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000671static void XMLCDECL
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000672xmlHTMLWarning(void *ctx, const char *msg, ...)
673{
674 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
675 xmlParserInputPtr input;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000676 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000677 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000678
679 buffer[0] = 0;
680 input = ctxt->input;
681 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000682 input = ctxt->inputTab[ctxt->inputNr - 2];
683 }
Daniel Veillardf1edb102009-08-10 14:43:18 +0200684
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000685
686 xmlHTMLPrintFileInfo(input);
Daniel Veillardf1edb102009-08-10 14:43:18 +0200687
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000688 xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000689 va_start(args, msg);
Daniel Veillardf1edb102009-08-10 14:43:18 +0200690 len = strlen(buffer);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000691 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000692 va_end(args);
693 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000694 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000695
696 xmlHTMLPrintFileContext(input);
697 xmlHTMLEncodeSend();
698}
699
700/**
701 * xmlHTMLValidityError:
702 * @ctx: an XML parser context
703 * @msg: the message to display/transmit
704 * @...: extra parameters for the message display
Daniel Veillardf1edb102009-08-10 14:43:18 +0200705 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000706 * Display and format an validity error messages, gives file,
707 * line, position and extra parameters.
708 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000709static void XMLCDECL
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000710xmlHTMLValidityError(void *ctx, const char *msg, ...)
711{
712 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
713 xmlParserInputPtr input;
714 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000715 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000716
717 buffer[0] = 0;
718 input = ctxt->input;
719 if ((input->filename == NULL) && (ctxt->inputNr > 1))
720 input = ctxt->inputTab[ctxt->inputNr - 2];
Daniel Veillardf1edb102009-08-10 14:43:18 +0200721
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000722 xmlHTMLPrintFileInfo(input);
723
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000724 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000725 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000726 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000727 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000728 va_end(args);
729 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000730 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000731
732 xmlHTMLPrintFileContext(input);
733 xmlHTMLEncodeSend();
Daniel Veillard9fcb4912005-03-16 12:57:31 +0000734 progresult = XMLLINT_ERR_VALID;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000735}
736
737/**
738 * xmlHTMLValidityWarning:
739 * @ctx: an XML parser context
740 * @msg: the message to display/transmit
741 * @...: extra parameters for the message display
Daniel Veillardf1edb102009-08-10 14:43:18 +0200742 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000743 * Display and format a validity warning messages, gives file, line,
744 * position and extra parameters.
745 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000746static void XMLCDECL
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000747xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
748{
749 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
750 xmlParserInputPtr input;
751 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000752 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000753
754 buffer[0] = 0;
755 input = ctxt->input;
756 if ((input->filename == NULL) && (ctxt->inputNr > 1))
757 input = ctxt->inputTab[ctxt->inputNr - 2];
758
759 xmlHTMLPrintFileInfo(input);
Daniel Veillardf1edb102009-08-10 14:43:18 +0200760
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000761 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000762 va_start(args, msg);
Daniel Veillardf1edb102009-08-10 14:43:18 +0200763 len = strlen(buffer);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000764 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000765 va_end(args);
766 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000767 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000768
769 xmlHTMLPrintFileContext(input);
770 xmlHTMLEncodeSend();
771}
772
773/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +0200774 * *
775 * Shell Interface *
776 * *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000777 ************************************************************************/
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000778#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000779#ifdef LIBXML_XPATH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000780/**
781 * xmlShellReadline:
782 * @prompt: the prompt value
783 *
784 * Read a string
Daniel Veillardf1edb102009-08-10 14:43:18 +0200785 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000786 * Returns a pointer to it or NULL on EOF the caller is expected to
787 * free the returned string.
788 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000789static char *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000790xmlShellReadline(char *prompt) {
791#ifdef HAVE_LIBREADLINE
792 char *line_read;
793
794 /* Get a line from the user. */
795 line_read = readline (prompt);
796
797 /* If the line has any text in it, save it on the history. */
798 if (line_read && *line_read)
799 add_history (line_read);
800
801 return (line_read);
802#else
803 char line_read[501];
Daniel Veillard29e43992001-12-13 22:21:58 +0000804 char *ret;
805 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000806
807 if (prompt != NULL)
808 fprintf(stdout, "%s", prompt);
809 if (!fgets(line_read, 500, stdin))
810 return(NULL);
811 line_read[500] = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000812 len = strlen(line_read);
813 ret = (char *) malloc(len + 1);
814 if (ret != NULL) {
815 memcpy (ret, line_read, len + 1);
816 }
817 return(ret);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000818#endif
819}
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000820#endif /* LIBXML_XPATH_ENABLED */
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000821#endif /* LIBXML_DEBUG_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000822
823/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +0200824 * *
825 * I/O Interfaces *
826 * *
Daniel Veillard5e873c42000-04-12 13:27:38 +0000827 ************************************************************************/
828
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000829static int myRead(FILE *f, char * buf, int len) {
830 return(fread(buf, 1, len, f));
Daniel Veillard5e873c42000-04-12 13:27:38 +0000831}
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000832static void myClose(FILE *f) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000833 if (f != stdin) {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000834 fclose(f);
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000835 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000836}
837
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000838/************************************************************************
839 * *
Daniel Veillardf1edb102009-08-10 14:43:18 +0200840 * SAX based tests *
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000841 * *
842 ************************************************************************/
843
844/*
845 * empty SAX block
846 */
Daniel Veillard24505b02005-07-28 23:49:35 +0000847static xmlSAXHandler emptySAXHandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000848 NULL, /* internalSubset */
849 NULL, /* isStandalone */
850 NULL, /* hasInternalSubset */
851 NULL, /* hasExternalSubset */
852 NULL, /* resolveEntity */
853 NULL, /* getEntity */
854 NULL, /* entityDecl */
855 NULL, /* notationDecl */
856 NULL, /* attributeDecl */
857 NULL, /* elementDecl */
858 NULL, /* unparsedEntityDecl */
859 NULL, /* setDocumentLocator */
860 NULL, /* startDocument */
861 NULL, /* endDocument */
862 NULL, /* startElement */
863 NULL, /* endElement */
864 NULL, /* reference */
865 NULL, /* characters */
866 NULL, /* ignorableWhitespace */
867 NULL, /* processingInstruction */
868 NULL, /* comment */
869 NULL, /* xmlParserWarning */
870 NULL, /* xmlParserError */
871 NULL, /* xmlParserError */
872 NULL, /* getParameterEntity */
873 NULL, /* cdataBlock; */
874 NULL, /* externalSubset; */
Daniel Veillard971771e2005-07-09 17:32:57 +0000875 XML_SAX2_MAGIC,
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000876 NULL,
877 NULL, /* startElementNs */
878 NULL, /* endElementNs */
879 NULL /* xmlStructuredErrorFunc */
880};
881
Daniel Veillard24505b02005-07-28 23:49:35 +0000882static xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000883extern xmlSAXHandlerPtr debugSAXHandler;
884static int callbacks;
885
886/**
887 * isStandaloneDebug:
888 * @ctxt: An XML parser context
889 *
890 * Is this document tagged standalone ?
891 *
892 * Returns 1 if true
893 */
894static int
895isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
896{
897 callbacks++;
898 if (noout)
899 return(0);
900 fprintf(stdout, "SAX.isStandalone()\n");
901 return(0);
902}
903
904/**
905 * hasInternalSubsetDebug:
906 * @ctxt: An XML parser context
907 *
908 * Does this document has an internal subset
909 *
910 * Returns 1 if true
911 */
912static int
913hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
914{
915 callbacks++;
916 if (noout)
917 return(0);
918 fprintf(stdout, "SAX.hasInternalSubset()\n");
919 return(0);
920}
921
922/**
923 * hasExternalSubsetDebug:
924 * @ctxt: An XML parser context
925 *
926 * Does this document has an external subset
927 *
928 * Returns 1 if true
929 */
930static int
931hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
932{
933 callbacks++;
934 if (noout)
935 return(0);
936 fprintf(stdout, "SAX.hasExternalSubset()\n");
937 return(0);
938}
939
940/**
941 * internalSubsetDebug:
942 * @ctxt: An XML parser context
943 *
944 * Does this document has an internal subset
945 */
946static void
947internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
948 const xmlChar *ExternalID, const xmlChar *SystemID)
949{
950 callbacks++;
951 if (noout)
952 return;
953 fprintf(stdout, "SAX.internalSubset(%s,", name);
954 if (ExternalID == NULL)
955 fprintf(stdout, " ,");
956 else
957 fprintf(stdout, " %s,", ExternalID);
958 if (SystemID == NULL)
959 fprintf(stdout, " )\n");
960 else
961 fprintf(stdout, " %s)\n", SystemID);
962}
963
964/**
965 * externalSubsetDebug:
966 * @ctxt: An XML parser context
967 *
968 * Does this document has an external subset
969 */
970static void
971externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
972 const xmlChar *ExternalID, const xmlChar *SystemID)
973{
974 callbacks++;
975 if (noout)
976 return;
977 fprintf(stdout, "SAX.externalSubset(%s,", name);
978 if (ExternalID == NULL)
979 fprintf(stdout, " ,");
980 else
981 fprintf(stdout, " %s,", ExternalID);
982 if (SystemID == NULL)
983 fprintf(stdout, " )\n");
984 else
985 fprintf(stdout, " %s)\n", SystemID);
986}
987
988/**
989 * resolveEntityDebug:
990 * @ctxt: An XML parser context
991 * @publicId: The public ID of the entity
992 * @systemId: The system ID of the entity
993 *
994 * Special entity resolver, better left to the parser, it has
995 * more context than the application layer.
996 * The default behaviour is to NOT resolve the entities, in that case
997 * the ENTITY_REF nodes are built in the structure (and the parameter
998 * values).
999 *
1000 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
1001 */
1002static xmlParserInputPtr
1003resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
1004{
1005 callbacks++;
1006 if (noout)
1007 return(NULL);
1008 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1009
Daniel Veillardf1edb102009-08-10 14:43:18 +02001010
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001011 fprintf(stdout, "SAX.resolveEntity(");
1012 if (publicId != NULL)
1013 fprintf(stdout, "%s", (char *)publicId);
1014 else
1015 fprintf(stdout, " ");
1016 if (systemId != NULL)
1017 fprintf(stdout, ", %s)\n", (char *)systemId);
1018 else
1019 fprintf(stdout, ", )\n");
1020 return(NULL);
1021}
1022
1023/**
1024 * getEntityDebug:
1025 * @ctxt: An XML parser context
1026 * @name: The entity name
1027 *
1028 * Get an entity by name
1029 *
1030 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
1031 */
1032static xmlEntityPtr
1033getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1034{
1035 callbacks++;
1036 if (noout)
1037 return(NULL);
1038 fprintf(stdout, "SAX.getEntity(%s)\n", name);
1039 return(NULL);
1040}
1041
1042/**
1043 * getParameterEntityDebug:
1044 * @ctxt: An XML parser context
1045 * @name: The entity name
1046 *
1047 * Get a parameter entity by name
1048 *
1049 * Returns the xmlParserInputPtr
1050 */
1051static xmlEntityPtr
1052getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1053{
1054 callbacks++;
1055 if (noout)
1056 return(NULL);
1057 fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
1058 return(NULL);
1059}
1060
1061
1062/**
1063 * entityDeclDebug:
1064 * @ctxt: An XML parser context
Daniel Veillardf1edb102009-08-10 14:43:18 +02001065 * @name: the entity name
1066 * @type: the entity type
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001067 * @publicId: The public ID of the entity
1068 * @systemId: The system ID of the entity
1069 * @content: the entity value (without processing).
1070 *
1071 * An entity definition has been parsed
1072 */
1073static void
1074entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
1075 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
1076{
1077const xmlChar *nullstr = BAD_CAST "(null)";
1078 /* not all libraries handle printing null pointers nicely */
1079 if (publicId == NULL)
1080 publicId = nullstr;
1081 if (systemId == NULL)
1082 systemId = nullstr;
1083 if (content == NULL)
1084 content = (xmlChar *)nullstr;
1085 callbacks++;
1086 if (noout)
1087 return;
1088 fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
1089 name, type, publicId, systemId, content);
1090}
1091
1092/**
1093 * attributeDeclDebug:
1094 * @ctxt: An XML parser context
Daniel Veillardf1edb102009-08-10 14:43:18 +02001095 * @name: the attribute name
1096 * @type: the attribute type
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001097 *
1098 * An attribute definition has been parsed
1099 */
1100static void
1101attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar * elem,
1102 const xmlChar * name, int type, int def,
1103 const xmlChar * defaultValue, xmlEnumerationPtr tree)
1104{
1105 callbacks++;
1106 if (noout)
1107 return;
1108 if (defaultValue == NULL)
1109 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
1110 elem, name, type, def);
1111 else
1112 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
1113 elem, name, type, def, defaultValue);
1114 xmlFreeEnumeration(tree);
1115}
1116
1117/**
1118 * elementDeclDebug:
1119 * @ctxt: An XML parser context
Daniel Veillardf1edb102009-08-10 14:43:18 +02001120 * @name: the element name
1121 * @type: the element type
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001122 * @content: the element value (without processing).
1123 *
1124 * An element definition has been parsed
1125 */
1126static void
1127elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
1128 xmlElementContentPtr content ATTRIBUTE_UNUSED)
1129{
1130 callbacks++;
1131 if (noout)
1132 return;
1133 fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
1134 name, type);
1135}
1136
1137/**
1138 * notationDeclDebug:
1139 * @ctxt: An XML parser context
1140 * @name: The name of the notation
1141 * @publicId: The public ID of the entity
1142 * @systemId: The system ID of the entity
1143 *
1144 * What to do when a notation declaration has been parsed.
1145 */
1146static void
1147notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
1148 const xmlChar *publicId, const xmlChar *systemId)
1149{
1150 callbacks++;
1151 if (noout)
1152 return;
1153 fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
1154 (char *) name, (char *) publicId, (char *) systemId);
1155}
1156
1157/**
1158 * unparsedEntityDeclDebug:
1159 * @ctxt: An XML parser context
1160 * @name: The name of the entity
1161 * @publicId: The public ID of the entity
1162 * @systemId: The system ID of the entity
1163 * @notationName: the name of the notation
1164 *
1165 * What to do when an unparsed entity declaration is parsed
1166 */
1167static void
1168unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
1169 const xmlChar *publicId, const xmlChar *systemId,
1170 const xmlChar *notationName)
1171{
1172const xmlChar *nullstr = BAD_CAST "(null)";
1173
1174 if (publicId == NULL)
1175 publicId = nullstr;
1176 if (systemId == NULL)
1177 systemId = nullstr;
1178 if (notationName == NULL)
1179 notationName = nullstr;
1180 callbacks++;
1181 if (noout)
1182 return;
1183 fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
1184 (char *) name, (char *) publicId, (char *) systemId,
1185 (char *) notationName);
1186}
1187
1188/**
1189 * setDocumentLocatorDebug:
1190 * @ctxt: An XML parser context
1191 * @loc: A SAX Locator
1192 *
1193 * Receive the document locator at startup, actually xmlDefaultSAXLocator
1194 * Everything is available on the context, so this is useless in our case.
1195 */
1196static void
1197setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
1198{
1199 callbacks++;
1200 if (noout)
1201 return;
1202 fprintf(stdout, "SAX.setDocumentLocator()\n");
1203}
1204
1205/**
1206 * startDocumentDebug:
1207 * @ctxt: An XML parser context
1208 *
1209 * called when the document start being processed.
1210 */
1211static void
1212startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
1213{
1214 callbacks++;
1215 if (noout)
1216 return;
1217 fprintf(stdout, "SAX.startDocument()\n");
1218}
1219
1220/**
1221 * endDocumentDebug:
1222 * @ctxt: An XML parser context
1223 *
1224 * called when the document end has been detected.
1225 */
1226static void
1227endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
1228{
1229 callbacks++;
1230 if (noout)
1231 return;
1232 fprintf(stdout, "SAX.endDocument()\n");
1233}
1234
1235/**
1236 * startElementDebug:
1237 * @ctxt: An XML parser context
1238 * @name: The element name
1239 *
1240 * called when an opening tag has been processed.
1241 */
1242static void
1243startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
1244{
1245 int i;
1246
1247 callbacks++;
1248 if (noout)
1249 return;
1250 fprintf(stdout, "SAX.startElement(%s", (char *) name);
1251 if (atts != NULL) {
1252 for (i = 0;(atts[i] != NULL);i++) {
1253 fprintf(stdout, ", %s='", atts[i++]);
1254 if (atts[i] != NULL)
1255 fprintf(stdout, "%s'", atts[i]);
1256 }
1257 }
1258 fprintf(stdout, ")\n");
1259}
1260
1261/**
1262 * endElementDebug:
1263 * @ctxt: An XML parser context
1264 * @name: The element name
1265 *
1266 * called when the end of an element has been detected.
1267 */
1268static void
1269endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1270{
1271 callbacks++;
1272 if (noout)
1273 return;
1274 fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
1275}
1276
1277/**
1278 * charactersDebug:
1279 * @ctxt: An XML parser context
1280 * @ch: a xmlChar string
1281 * @len: the number of xmlChar
1282 *
1283 * receiving some chars from the parser.
1284 * Question: how much at a time ???
1285 */
1286static void
1287charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
1288{
1289 char out[40];
1290 int i;
1291
1292 callbacks++;
1293 if (noout)
1294 return;
1295 for (i = 0;(i<len) && (i < 30);i++)
1296 out[i] = ch[i];
1297 out[i] = 0;
1298
1299 fprintf(stdout, "SAX.characters(%s, %d)\n", out, len);
1300}
1301
1302/**
1303 * referenceDebug:
1304 * @ctxt: An XML parser context
1305 * @name: The entity name
1306 *
Daniel Veillardf1edb102009-08-10 14:43:18 +02001307 * called when an entity reference is detected.
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001308 */
1309static void
1310referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1311{
1312 callbacks++;
1313 if (noout)
1314 return;
1315 fprintf(stdout, "SAX.reference(%s)\n", name);
1316}
1317
1318/**
1319 * ignorableWhitespaceDebug:
1320 * @ctxt: An XML parser context
1321 * @ch: a xmlChar string
1322 * @start: the first char in the string
1323 * @len: the number of xmlChar
1324 *
1325 * receiving some ignorable whitespaces from the parser.
1326 * Question: how much at a time ???
1327 */
1328static void
1329ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
1330{
1331 char out[40];
1332 int i;
1333
1334 callbacks++;
1335 if (noout)
1336 return;
1337 for (i = 0;(i<len) && (i < 30);i++)
1338 out[i] = ch[i];
1339 out[i] = 0;
1340 fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", out, len);
1341}
1342
1343/**
1344 * processingInstructionDebug:
1345 * @ctxt: An XML parser context
1346 * @target: the target name
1347 * @data: the PI data's
1348 * @len: the number of xmlChar
1349 *
1350 * A processing instruction has been parsed.
1351 */
1352static void
1353processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
1354 const xmlChar *data)
1355{
1356 callbacks++;
1357 if (noout)
1358 return;
1359 if (data != NULL)
1360 fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
1361 (char *) target, (char *) data);
1362 else
1363 fprintf(stdout, "SAX.processingInstruction(%s, NULL)\n",
1364 (char *) target);
1365}
1366
1367/**
1368 * cdataBlockDebug:
1369 * @ctx: the user data (XML parser context)
1370 * @value: The pcdata content
1371 * @len: the block length
1372 *
1373 * called when a pcdata block has been parsed
1374 */
1375static void
1376cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
1377{
1378 callbacks++;
1379 if (noout)
1380 return;
1381 fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
1382 (char *) value, len);
1383}
1384
1385/**
1386 * commentDebug:
1387 * @ctxt: An XML parser context
1388 * @value: the comment content
1389 *
1390 * A comment has been parsed.
1391 */
1392static void
1393commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
1394{
1395 callbacks++;
1396 if (noout)
1397 return;
1398 fprintf(stdout, "SAX.comment(%s)\n", value);
1399}
1400
1401/**
1402 * warningDebug:
1403 * @ctxt: An XML parser context
1404 * @msg: the message to display/transmit
1405 * @...: extra parameters for the message display
1406 *
1407 * Display and format a warning messages, gives file, line, position and
1408 * extra parameters.
1409 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001410static void XMLCDECL
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001411warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1412{
1413 va_list args;
1414
1415 callbacks++;
1416 if (noout)
1417 return;
1418 va_start(args, msg);
1419 fprintf(stdout, "SAX.warning: ");
1420 vfprintf(stdout, msg, args);
1421 va_end(args);
1422}
1423
1424/**
1425 * errorDebug:
1426 * @ctxt: An XML parser context
1427 * @msg: the message to display/transmit
1428 * @...: extra parameters for the message display
1429 *
1430 * Display and format a error messages, gives file, line, position and
1431 * extra parameters.
1432 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001433static void XMLCDECL
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001434errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1435{
1436 va_list args;
1437
1438 callbacks++;
1439 if (noout)
1440 return;
1441 va_start(args, msg);
1442 fprintf(stdout, "SAX.error: ");
1443 vfprintf(stdout, msg, args);
1444 va_end(args);
1445}
1446
1447/**
1448 * fatalErrorDebug:
1449 * @ctxt: An XML parser context
1450 * @msg: the message to display/transmit
1451 * @...: extra parameters for the message display
1452 *
1453 * Display and format a fatalError messages, gives file, line, position and
1454 * extra parameters.
1455 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001456static void XMLCDECL
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001457fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1458{
1459 va_list args;
1460
1461 callbacks++;
1462 if (noout)
1463 return;
1464 va_start(args, msg);
1465 fprintf(stdout, "SAX.fatalError: ");
1466 vfprintf(stdout, msg, args);
1467 va_end(args);
1468}
1469
Daniel Veillard24505b02005-07-28 23:49:35 +00001470static xmlSAXHandler debugSAXHandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001471 internalSubsetDebug,
1472 isStandaloneDebug,
1473 hasInternalSubsetDebug,
1474 hasExternalSubsetDebug,
1475 resolveEntityDebug,
1476 getEntityDebug,
1477 entityDeclDebug,
1478 notationDeclDebug,
1479 attributeDeclDebug,
1480 elementDeclDebug,
1481 unparsedEntityDeclDebug,
1482 setDocumentLocatorDebug,
1483 startDocumentDebug,
1484 endDocumentDebug,
1485 startElementDebug,
1486 endElementDebug,
1487 referenceDebug,
1488 charactersDebug,
1489 ignorableWhitespaceDebug,
1490 processingInstructionDebug,
1491 commentDebug,
1492 warningDebug,
1493 errorDebug,
1494 fatalErrorDebug,
1495 getParameterEntityDebug,
1496 cdataBlockDebug,
1497 externalSubsetDebug,
1498 1,
1499 NULL,
1500 NULL,
1501 NULL,
1502 NULL
1503};
1504
1505xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
1506
1507/*
1508 * SAX2 specific callbacks
1509 */
1510/**
1511 * startElementNsDebug:
1512 * @ctxt: An XML parser context
1513 * @name: The element name
1514 *
1515 * called when an opening tag has been processed.
1516 */
1517static void
1518startElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
1519 const xmlChar *localname,
1520 const xmlChar *prefix,
1521 const xmlChar *URI,
1522 int nb_namespaces,
1523 const xmlChar **namespaces,
1524 int nb_attributes,
1525 int nb_defaulted,
1526 const xmlChar **attributes)
1527{
1528 int i;
1529
1530 callbacks++;
1531 if (noout)
1532 return;
1533 fprintf(stdout, "SAX.startElementNs(%s", (char *) localname);
1534 if (prefix == NULL)
1535 fprintf(stdout, ", NULL");
1536 else
1537 fprintf(stdout, ", %s", (char *) prefix);
1538 if (URI == NULL)
1539 fprintf(stdout, ", NULL");
1540 else
1541 fprintf(stdout, ", '%s'", (char *) URI);
1542 fprintf(stdout, ", %d", nb_namespaces);
Daniel Veillardf1edb102009-08-10 14:43:18 +02001543
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001544 if (namespaces != NULL) {
1545 for (i = 0;i < nb_namespaces * 2;i++) {
1546 fprintf(stdout, ", xmlns");
1547 if (namespaces[i] != NULL)
1548 fprintf(stdout, ":%s", namespaces[i]);
1549 i++;
1550 fprintf(stdout, "='%s'", namespaces[i]);
1551 }
1552 }
1553 fprintf(stdout, ", %d, %d", nb_attributes, nb_defaulted);
1554 if (attributes != NULL) {
1555 for (i = 0;i < nb_attributes * 5;i += 5) {
1556 if (attributes[i + 1] != NULL)
1557 fprintf(stdout, ", %s:%s='", attributes[i + 1], attributes[i]);
1558 else
1559 fprintf(stdout, ", %s='", attributes[i]);
1560 fprintf(stdout, "%.4s...', %d", attributes[i + 3],
1561 (int)(attributes[i + 4] - attributes[i + 3]));
1562 }
1563 }
1564 fprintf(stdout, ")\n");
1565}
1566
1567/**
1568 * endElementDebug:
1569 * @ctxt: An XML parser context
1570 * @name: The element name
1571 *
1572 * called when the end of an element has been detected.
1573 */
1574static void
1575endElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
1576 const xmlChar *localname,
1577 const xmlChar *prefix,
1578 const xmlChar *URI)
1579{
1580 callbacks++;
1581 if (noout)
1582 return;
1583 fprintf(stdout, "SAX.endElementNs(%s", (char *) localname);
1584 if (prefix == NULL)
1585 fprintf(stdout, ", NULL");
1586 else
1587 fprintf(stdout, ", %s", (char *) prefix);
1588 if (URI == NULL)
1589 fprintf(stdout, ", NULL)\n");
1590 else
1591 fprintf(stdout, ", '%s')\n", (char *) URI);
1592}
1593
Daniel Veillard24505b02005-07-28 23:49:35 +00001594static xmlSAXHandler debugSAX2HandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001595 internalSubsetDebug,
1596 isStandaloneDebug,
1597 hasInternalSubsetDebug,
1598 hasExternalSubsetDebug,
1599 resolveEntityDebug,
1600 getEntityDebug,
1601 entityDeclDebug,
1602 notationDeclDebug,
1603 attributeDeclDebug,
1604 elementDeclDebug,
1605 unparsedEntityDeclDebug,
1606 setDocumentLocatorDebug,
1607 startDocumentDebug,
1608 endDocumentDebug,
1609 NULL,
1610 NULL,
1611 referenceDebug,
1612 charactersDebug,
1613 ignorableWhitespaceDebug,
1614 processingInstructionDebug,
1615 commentDebug,
1616 warningDebug,
1617 errorDebug,
1618 fatalErrorDebug,
1619 getParameterEntityDebug,
1620 cdataBlockDebug,
1621 externalSubsetDebug,
1622 XML_SAX2_MAGIC,
1623 NULL,
1624 startElementNsDebug,
1625 endElementNsDebug,
1626 NULL
1627};
1628
Daniel Veillard24505b02005-07-28 23:49:35 +00001629static xmlSAXHandlerPtr debugSAX2Handler = &debugSAX2HandlerStruct;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001630
1631static void
1632testSAX(const char *filename) {
1633 xmlSAXHandlerPtr handler;
1634 const char *user_data = "user_data"; /* mostly for debugging */
1635 xmlParserInputBufferPtr buf = NULL;
1636 xmlParserInputPtr inputStream;
1637 xmlParserCtxtPtr ctxt = NULL;
1638 xmlSAXHandlerPtr old_sax = NULL;
1639
1640 callbacks = 0;
1641
1642 if (noout) {
1643 handler = emptySAXHandler;
Daniel Veillard78dfc9f2005-07-10 22:30:30 +00001644#ifdef LIBXML_SAX1_ENABLED
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001645 } else if (sax1) {
1646 handler = debugSAXHandler;
Daniel Veillard78dfc9f2005-07-10 22:30:30 +00001647#endif
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001648 } else {
1649 handler = debugSAX2Handler;
1650 }
1651
1652 /*
1653 * it's not the simplest code but the most generic in term of I/O
1654 */
1655 buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
1656 if (buf == NULL) {
1657 goto error;
1658 }
1659
1660#ifdef LIBXML_SCHEMAS_ENABLED
1661 if (wxschemas != NULL) {
1662 int ret;
1663 xmlSchemaValidCtxtPtr vctxt;
1664
1665 vctxt = xmlSchemaNewValidCtxt(wxschemas);
1666 xmlSchemaSetValidErrors(vctxt,
1667 (xmlSchemaValidityErrorFunc) fprintf,
1668 (xmlSchemaValidityWarningFunc) fprintf,
1669 stderr);
1670
Daniel Veillard971771e2005-07-09 17:32:57 +00001671 ret = xmlSchemaValidateStream(vctxt, buf, 0, handler,
1672 (void *)user_data);
1673 if (repeat == 0) {
1674 if (ret == 0) {
1675 fprintf(stderr, "%s validates\n", filename);
1676 } else if (ret > 0) {
1677 fprintf(stderr, "%s fails to validate\n", filename);
1678 progresult = XMLLINT_ERR_VALID;
1679 } else {
1680 fprintf(stderr, "%s validation generated an internal error\n",
1681 filename);
1682 progresult = XMLLINT_ERR_VALID;
1683 }
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001684 }
1685 xmlSchemaFreeValidCtxt(vctxt);
1686 } else
1687#endif
1688 {
1689 /*
1690 * Create the parser context amd hook the input
1691 */
1692 ctxt = xmlNewParserCtxt();
1693 if (ctxt == NULL) {
1694 xmlFreeParserInputBuffer(buf);
1695 goto error;
1696 }
1697 old_sax = ctxt->sax;
1698 ctxt->sax = handler;
1699 ctxt->userData = (void *) user_data;
1700 inputStream = xmlNewIOInputStream(ctxt, buf, XML_CHAR_ENCODING_NONE);
1701 if (inputStream == NULL) {
1702 xmlFreeParserInputBuffer(buf);
1703 goto error;
1704 }
1705 inputPush(ctxt, inputStream);
Daniel Veillardf1edb102009-08-10 14:43:18 +02001706
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001707 /* do the parsing */
1708 xmlParseDocument(ctxt);
1709
1710 if (ctxt->myDoc != NULL) {
1711 fprintf(stderr, "SAX generated a doc !\n");
1712 xmlFreeDoc(ctxt->myDoc);
1713 ctxt->myDoc = NULL;
1714 }
1715 }
1716
1717error:
1718 if (ctxt != NULL) {
1719 ctxt->sax = old_sax;
1720 xmlFreeParserCtxt(ctxt);
1721 }
1722}
1723
Daniel Veillard5e873c42000-04-12 13:27:38 +00001724/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +02001725 * *
1726 * Stream Test processing *
1727 * *
Daniel Veillard7704fb12003-01-03 16:19:51 +00001728 ************************************************************************/
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001729#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00001730static void processNode(xmlTextReaderPtr reader) {
Daniel Veillard198c1bf2003-10-20 17:07:41 +00001731 const xmlChar *name, *value;
Daniel Veillard16ef8002005-01-31 00:27:50 +00001732 int type, empty;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001733
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001734 type = xmlTextReaderNodeType(reader);
Daniel Veillard16ef8002005-01-31 00:27:50 +00001735 empty = xmlTextReaderIsEmptyElement(reader);
Daniel Veillard99737f52003-03-22 14:55:50 +00001736
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001737 if (debug) {
1738 name = xmlTextReaderConstName(reader);
1739 if (name == NULL)
1740 name = BAD_CAST "--";
Daniel Veillard7704fb12003-01-03 16:19:51 +00001741
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001742 value = xmlTextReaderConstValue(reader);
1743
Daniel Veillardf1edb102009-08-10 14:43:18 +02001744
1745 printf("%d %d %s %d %d",
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001746 xmlTextReaderDepth(reader),
1747 type,
1748 name,
Daniel Veillard16ef8002005-01-31 00:27:50 +00001749 empty,
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001750 xmlTextReaderHasValue(reader));
1751 if (value == NULL)
1752 printf("\n");
1753 else {
1754 printf(" %s\n", value);
1755 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001756 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001757#ifdef LIBXML_PATTERN_ENABLED
1758 if (patternc) {
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001759 xmlChar *path = NULL;
1760 int match = -1;
Daniel Veillardf1edb102009-08-10 14:43:18 +02001761
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001762 if (type == XML_READER_TYPE_ELEMENT) {
1763 /* do the check only on element start */
1764 match = xmlPatternMatch(patternc, xmlTextReaderCurrentNode(reader));
1765
1766 if (match) {
Daniel Veillardf1edb102009-08-10 14:43:18 +02001767#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001768 path = xmlGetNodePath(xmlTextReaderCurrentNode(reader));
1769 printf("Node %s matches pattern %s\n", path, pattern);
Daniel Veillardf1edb102009-08-10 14:43:18 +02001770#else
1771 printf("Node %s matches pattern %s\n",
1772 xmlTextReaderConstName(reader), pattern);
1773#endif
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001774 }
1775 }
1776 if (patstream != NULL) {
1777 int ret;
1778
1779 if (type == XML_READER_TYPE_ELEMENT) {
1780 ret = xmlStreamPush(patstream,
1781 xmlTextReaderConstLocalName(reader),
1782 xmlTextReaderConstNamespaceUri(reader));
1783 if (ret < 0) {
1784 fprintf(stderr, "xmlStreamPush() failure\n");
1785 xmlFreeStreamCtxt(patstream);
1786 patstream = NULL;
1787 } else if (ret != match) {
Daniel Veillardf1edb102009-08-10 14:43:18 +02001788#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001789 if (path == NULL) {
1790 path = xmlGetNodePath(
1791 xmlTextReaderCurrentNode(reader));
1792 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02001793#endif
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001794 fprintf(stderr,
1795 "xmlPatternMatch and xmlStreamPush disagree\n");
Daniel Veillardf1edb102009-08-10 14:43:18 +02001796 if (path != NULL)
1797 fprintf(stderr, " pattern %s node %s\n",
1798 pattern, path);
1799 else
1800 fprintf(stderr, " pattern %s node %s\n",
1801 pattern, xmlTextReaderConstName(reader));
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001802 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001803
Daniel Veillardf1edb102009-08-10 14:43:18 +02001804 }
Daniel Veillard16ef8002005-01-31 00:27:50 +00001805 if ((type == XML_READER_TYPE_END_ELEMENT) ||
1806 ((type == XML_READER_TYPE_ELEMENT) && (empty))) {
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001807 ret = xmlStreamPop(patstream);
1808 if (ret < 0) {
1809 fprintf(stderr, "xmlStreamPop() failure\n");
1810 xmlFreeStreamCtxt(patstream);
1811 patstream = NULL;
1812 }
1813 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001814 }
Daniel Veillardf9d16912005-01-30 22:36:30 +00001815 if (path != NULL)
1816 xmlFree(path);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001817 }
1818#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001819}
1820
1821static void streamFile(char *filename) {
1822 xmlTextReaderPtr reader;
1823 int ret;
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001824#ifdef HAVE_SYS_MMAN_H
1825 int fd = -1;
1826 struct stat info;
1827 const char *base = NULL;
1828 xmlParserInputBufferPtr input = NULL;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001829
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001830 if (memory) {
Daniel Veillardf1edb102009-08-10 14:43:18 +02001831 if (stat(filename, &info) < 0)
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001832 return;
1833 if ((fd = open(filename, O_RDONLY)) < 0)
1834 return;
1835 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
1836 if (base == (void *) MAP_FAILED)
1837 return;
1838
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001839 reader = xmlReaderForMemory(base, info.st_size, filename,
1840 NULL, options);
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001841 } else
1842#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001843 reader = xmlReaderForFile(filename, NULL, options);
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001844#ifdef LIBXML_PATTERN_ENABLED
Daniel Veillardd4301ab2005-02-03 22:24:10 +00001845 if (pattern != NULL) {
1846 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
1847 if (patternc == NULL) {
1848 xmlGenericError(xmlGenericErrorContext,
1849 "Pattern %s failed to compile\n", pattern);
1850 progresult = XMLLINT_ERR_SCHEMAPAT;
1851 pattern = NULL;
1852 }
1853 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001854 if (patternc != NULL) {
1855 patstream = xmlPatternGetStreamCtxt(patternc);
1856 if (patstream != NULL) {
1857 ret = xmlStreamPush(patstream, NULL, NULL);
1858 if (ret < 0) {
1859 fprintf(stderr, "xmlStreamPush() failure\n");
1860 xmlFreeStreamCtxt(patstream);
1861 patstream = NULL;
1862 }
1863 }
1864 }
1865#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001866
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001867
Daniel Veillard7704fb12003-01-03 16:19:51 +00001868 if (reader != NULL) {
Daniel Veillard4432df22003-09-28 18:58:27 +00001869#ifdef LIBXML_VALID_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00001870 if (valid)
1871 xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
Daniel Veillardce192eb2003-04-16 15:58:05 +00001872 else
Daniel Veillard4432df22003-09-28 18:58:27 +00001873#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardce192eb2003-04-16 15:58:05 +00001874 xmlTextReaderSetParserProp(reader, XML_PARSER_LOADDTD, 1);
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001875#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +00001876 if (relaxng != NULL) {
Daniel Veillard81514ba2003-09-16 23:17:26 +00001877 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001878 startTimer();
1879 }
1880 ret = xmlTextReaderRelaxNGValidate(reader, relaxng);
1881 if (ret < 0) {
1882 xmlGenericError(xmlGenericErrorContext,
1883 "Relax-NG schema %s failed to compile\n", relaxng);
William M. Brack8304d872004-06-08 13:29:32 +00001884 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillardce192eb2003-04-16 15:58:05 +00001885 relaxng = NULL;
1886 }
Daniel Veillard81514ba2003-09-16 23:17:26 +00001887 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001888 endTimer("Compiling the schemas");
1889 }
1890 }
Daniel Veillardf10ae122005-07-10 19:03:16 +00001891 if (schema != NULL) {
1892 if ((timing) && (!repeat)) {
1893 startTimer();
1894 }
1895 ret = xmlTextReaderSchemaValidate(reader, schema);
1896 if (ret < 0) {
1897 xmlGenericError(xmlGenericErrorContext,
1898 "XSD schema %s failed to compile\n", schema);
1899 progresult = XMLLINT_ERR_SCHEMACOMP;
1900 schema = NULL;
1901 }
1902 if ((timing) && (!repeat)) {
1903 endTimer("Compiling the schemas");
1904 }
1905 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001906#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001907
1908 /*
1909 * Process all nodes in sequence
1910 */
Daniel Veillard81514ba2003-09-16 23:17:26 +00001911 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001912 startTimer();
1913 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001914 ret = xmlTextReaderRead(reader);
1915 while (ret == 1) {
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001916 if ((debug)
1917#ifdef LIBXML_PATTERN_ENABLED
1918 || (patternc)
1919#endif
1920 )
Daniel Veillard7704fb12003-01-03 16:19:51 +00001921 processNode(reader);
1922 ret = xmlTextReaderRead(reader);
1923 }
Daniel Veillard81514ba2003-09-16 23:17:26 +00001924 if ((timing) && (!repeat)) {
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001925#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf54cd532004-02-25 11:52:31 +00001926 if (relaxng != NULL)
Daniel Veillard49138f12004-02-19 12:58:36 +00001927 endTimer("Parsing and validating");
1928 else
Daniel Veillardf54cd532004-02-25 11:52:31 +00001929#endif
Daniel Veillard4432df22003-09-28 18:58:27 +00001930#ifdef LIBXML_VALID_ENABLED
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001931 if (valid)
Daniel Veillardce192eb2003-04-16 15:58:05 +00001932 endTimer("Parsing and validating");
1933 else
Daniel Veillard4432df22003-09-28 18:58:27 +00001934#endif
Daniel Veillardf54cd532004-02-25 11:52:31 +00001935 endTimer("Parsing");
Daniel Veillardce192eb2003-04-16 15:58:05 +00001936 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001937
Daniel Veillard4432df22003-09-28 18:58:27 +00001938#ifdef LIBXML_VALID_ENABLED
Daniel Veillardf6bad792003-04-11 19:38:54 +00001939 if (valid) {
1940 if (xmlTextReaderIsValid(reader) != 1) {
1941 xmlGenericError(xmlGenericErrorContext,
1942 "Document %s does not validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001943 progresult = XMLLINT_ERR_VALID;
Daniel Veillardf6bad792003-04-11 19:38:54 +00001944 }
1945 }
Daniel Veillard4432df22003-09-28 18:58:27 +00001946#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001947#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf10ae122005-07-10 19:03:16 +00001948 if ((relaxng != NULL) || (schema != NULL)) {
Daniel Veillardf4e55762003-04-15 23:32:22 +00001949 if (xmlTextReaderIsValid(reader) != 1) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001950 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001951 progresult = XMLLINT_ERR_VALID;
Daniel Veillardf4e55762003-04-15 23:32:22 +00001952 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001953 fprintf(stderr, "%s validates\n", filename);
Daniel Veillardf4e55762003-04-15 23:32:22 +00001954 }
1955 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001956#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001957 /*
1958 * Done, cleanup and status
1959 */
1960 xmlFreeTextReader(reader);
1961 if (ret != 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001962 fprintf(stderr, "%s : failed to parse\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001963 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001964 }
1965 } else {
1966 fprintf(stderr, "Unable to open %s\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001967 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001968 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001969#ifdef LIBXML_PATTERN_ENABLED
1970 if (patstream != NULL) {
1971 xmlFreeStreamCtxt(patstream);
1972 patstream = NULL;
1973 }
1974#endif
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001975#ifdef HAVE_SYS_MMAN_H
1976 if (memory) {
1977 xmlFreeParserInputBuffer(input);
1978 munmap((char *) base, info.st_size);
1979 close(fd);
1980 }
1981#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001982}
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001983
1984static void walkDoc(xmlDocPtr doc) {
1985 xmlTextReaderPtr reader;
1986 int ret;
1987
Daniel Veillardd4301ab2005-02-03 22:24:10 +00001988#ifdef LIBXML_PATTERN_ENABLED
1989 xmlNodePtr root;
1990 const xmlChar *namespaces[22];
1991 int i;
1992 xmlNsPtr ns;
1993
1994 root = xmlDocGetRootElement(doc);
1995 for (ns = root->nsDef, i = 0;ns != NULL && i < 20;ns=ns->next) {
1996 namespaces[i++] = ns->href;
1997 namespaces[i++] = ns->prefix;
1998 }
1999 namespaces[i++] = NULL;
Daniel Veillard13cee4e2009-09-05 14:52:55 +02002000 namespaces[i] = NULL;
Daniel Veillardd4301ab2005-02-03 22:24:10 +00002001
2002 if (pattern != NULL) {
2003 patternc = xmlPatterncompile((const xmlChar *) pattern, doc->dict,
2004 0, &namespaces[0]);
2005 if (patternc == NULL) {
2006 xmlGenericError(xmlGenericErrorContext,
2007 "Pattern %s failed to compile\n", pattern);
2008 progresult = XMLLINT_ERR_SCHEMAPAT;
2009 pattern = NULL;
2010 }
2011 }
Daniel Veillard2b2e02d2005-02-05 23:20:22 +00002012 if (patternc != NULL) {
2013 patstream = xmlPatternGetStreamCtxt(patternc);
2014 if (patstream != NULL) {
2015 ret = xmlStreamPush(patstream, NULL, NULL);
2016 if (ret < 0) {
2017 fprintf(stderr, "xmlStreamPush() failure\n");
2018 xmlFreeStreamCtxt(patstream);
2019 patstream = NULL;
2020 }
2021 }
2022 }
Daniel Veillardd4301ab2005-02-03 22:24:10 +00002023#endif /* LIBXML_PATTERN_ENABLED */
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002024 reader = xmlReaderWalker(doc);
2025 if (reader != NULL) {
2026 if ((timing) && (!repeat)) {
2027 startTimer();
2028 }
2029 ret = xmlTextReaderRead(reader);
2030 while (ret == 1) {
Daniel Veillardb3de70c2003-12-02 22:32:15 +00002031 if ((debug)
2032#ifdef LIBXML_PATTERN_ENABLED
2033 || (patternc)
2034#endif
2035 )
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002036 processNode(reader);
2037 ret = xmlTextReaderRead(reader);
2038 }
2039 if ((timing) && (!repeat)) {
2040 endTimer("walking through the doc");
2041 }
2042 xmlFreeTextReader(reader);
2043 if (ret != 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002044 fprintf(stderr, "failed to walk through the doc\n");
William M. Brack8304d872004-06-08 13:29:32 +00002045 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002046 }
2047 } else {
2048 fprintf(stderr, "Failed to crate a reader from the document\n");
William M. Brack8304d872004-06-08 13:29:32 +00002049 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002050 }
Daniel Veillard2b2e02d2005-02-05 23:20:22 +00002051#ifdef LIBXML_PATTERN_ENABLED
2052 if (patstream != NULL) {
2053 xmlFreeStreamCtxt(patstream);
2054 patstream = NULL;
2055 }
2056#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002057}
Daniel Veillard81273902003-09-30 00:43:48 +00002058#endif /* LIBXML_READER_ENABLED */
Daniel Veillard7704fb12003-01-03 16:19:51 +00002059
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002060#ifdef LIBXML_XPATH_ENABLED
2061/************************************************************************
2062 * *
2063 * XPath Query *
2064 * *
2065 ************************************************************************/
2066
2067static void doXPathDump(xmlXPathObjectPtr cur) {
2068 switch(cur->type) {
2069 case XPATH_NODESET: {
2070 int i;
2071 xmlNodePtr node;
2072#ifdef LIBXML_OUTPUT_ENABLED
2073 xmlSaveCtxtPtr ctxt;
2074
2075 if (cur->nodesetval->nodeNr <= 0) {
2076 fprintf(stderr, "XPath set is empty\n");
2077 progresult = XMLLINT_ERR_XPATH;
2078 break;
2079 }
2080 ctxt = xmlSaveToFd(1, NULL, 0);
2081 if (ctxt == NULL) {
2082 fprintf(stderr, "Out of memory for XPath\n");
2083 progresult = XMLLINT_ERR_MEM;
2084 return;
2085 }
2086 for (i = 0;i < cur->nodesetval->nodeNr;i++) {
2087 node = cur->nodesetval->nodeTab[i];
2088 xmlSaveTree(ctxt, node);
2089 }
2090 xmlSaveClose(ctxt);
2091#else
2092 printf("xpath returned %d nodes\n", cur->nodesetval->nodeNr);
2093#endif
2094 break;
2095 }
2096 case XPATH_BOOLEAN:
2097 if (cur->boolval) printf("true");
2098 else printf("false");
2099 break;
2100 case XPATH_NUMBER:
2101 switch (xmlXPathIsInf(cur->floatval)) {
2102 case 1:
2103 printf("Infinity");
2104 break;
2105 case -1:
2106 printf("-Infinity");
2107 break;
2108 default:
2109 if (xmlXPathIsNaN(cur->floatval)) {
2110 printf("NaN");
2111 } else {
2112 printf("%0g", cur->floatval);
2113 }
2114 }
2115 break;
2116 case XPATH_STRING:
2117 printf("%s", (const char *) cur->stringval);
2118 break;
2119 case XPATH_UNDEFINED:
2120 fprintf(stderr, "XPath Object is uninitialized\n");
2121 progresult = XMLLINT_ERR_XPATH;
2122 break;
2123 default:
2124 fprintf(stderr, "XPath object of unexpected type\n");
2125 progresult = XMLLINT_ERR_XPATH;
2126 break;
2127 }
2128}
2129
2130static void doXPathQuery(xmlDocPtr doc, const char *query) {
2131 xmlXPathContextPtr ctxt;
2132 xmlXPathObjectPtr res;
2133
2134 ctxt = xmlXPathNewContext(doc);
2135 if (ctxt == NULL) {
2136 fprintf(stderr, "Out of memory for XPath\n");
2137 progresult = XMLLINT_ERR_MEM;
2138 return;
2139 }
2140 ctxt->node = xmlDocGetRootElement(doc);
2141 res = xmlXPathEval(BAD_CAST query, ctxt);
2142 xmlXPathFreeContext(ctxt);
2143
2144 if (res == NULL) {
2145 fprintf(stderr, "XPath evaluation failure\n");
2146 progresult = XMLLINT_ERR_XPATH;
2147 return;
2148 }
2149 doXPathDump(res);
2150 xmlXPathFreeObject(res);
2151}
2152#endif /* LIBXML_XPATH_ENABLED */
2153
Daniel Veillard7704fb12003-01-03 16:19:51 +00002154/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +02002155 * *
2156 * Tree Test processing *
2157 * *
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002158 ************************************************************************/
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002159static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
Daniel Veillard652327a2003-09-29 18:02:38 +00002160 xmlDocPtr doc = NULL;
2161#ifdef LIBXML_TREE_ENABLED
2162 xmlDocPtr tmp;
2163#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002164
Daniel Veillard48b2f892001-02-25 16:11:03 +00002165 if ((timing) && (!repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00002166 startTimer();
Daniel Veillardf1edb102009-08-10 14:43:18 +02002167
Daniel Veillard48b2f892001-02-25 16:11:03 +00002168
Daniel Veillard652327a2003-09-29 18:02:38 +00002169#ifdef LIBXML_TREE_ENABLED
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002170 if (filename == NULL) {
2171 if (generate) {
2172 xmlNodePtr n;
2173
2174 doc = xmlNewDoc(BAD_CAST "1.0");
Daniel Veillard95ddcd32004-10-26 21:53:55 +00002175 n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002176 xmlNodeSetContent(n, BAD_CAST "abc");
2177 xmlDocSetRootElement(doc, n);
2178 }
2179 }
Daniel Veillard652327a2003-09-29 18:02:38 +00002180#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002181#ifdef LIBXML_HTML_ENABLED
Daniel Veillard73b013f2003-09-30 12:36:01 +00002182#ifdef LIBXML_PUSH_ENABLED
William M. Brack78637da2003-07-31 14:47:38 +00002183 else if ((html) && (push)) {
2184 FILE *f;
2185
William M. Brack3403add2004-06-27 02:07:51 +00002186#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2187 f = fopen(filename, "rb");
2188#else
2189 f = fopen(filename, "r");
2190#endif
William M. Brack78637da2003-07-31 14:47:38 +00002191 if (f != NULL) {
2192 int res, size = 3;
2193 char chars[4096];
2194 htmlParserCtxtPtr ctxt;
2195
2196 /* if (repeat) */
2197 size = 4096;
2198 res = fread(chars, 1, 4, f);
2199 if (res > 0) {
2200 ctxt = htmlCreatePushParserCtxt(NULL, NULL,
William M. Brack1d75c8a2003-10-27 13:48:16 +00002201 chars, res, filename, XML_CHAR_ENCODING_NONE);
William M. Brack78637da2003-07-31 14:47:38 +00002202 while ((res = fread(chars, 1, size, f)) > 0) {
2203 htmlParseChunk(ctxt, chars, res, 0);
2204 }
2205 htmlParseChunk(ctxt, chars, 0, 1);
2206 doc = ctxt->myDoc;
2207 htmlFreeParserCtxt(ctxt);
2208 }
2209 fclose(f);
2210 }
2211 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00002212#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002213#ifdef HAVE_SYS_MMAN_H
2214 else if ((html) && (memory)) {
2215 int fd;
2216 struct stat info;
2217 const char *base;
Daniel Veillardf1edb102009-08-10 14:43:18 +02002218 if (stat(filename, &info) < 0)
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002219 return;
2220 if ((fd = open(filename, O_RDONLY)) < 0)
2221 return;
2222 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
2223 if (base == (void *) MAP_FAILED)
2224 return;
2225
2226 doc = htmlReadMemory((char *) base, info.st_size, filename,
2227 NULL, options);
Daniel Veillardf1edb102009-08-10 14:43:18 +02002228
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002229 munmap((char *) base, info.st_size);
2230 close(fd);
2231 }
2232#endif
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002233 else if (html) {
Daniel Veillard9475a352003-09-26 12:47:50 +00002234 doc = htmlReadFile(filename, NULL, options);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002235 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002236#endif /* LIBXML_HTML_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002237 else {
Daniel Veillard73b013f2003-09-30 12:36:01 +00002238#ifdef LIBXML_PUSH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002239 /*
2240 * build an XML tree from a string;
2241 */
2242 if (push) {
2243 FILE *f;
2244
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002245 /* '-' Usually means stdin -<sven@zen.org> */
2246 if ((filename[0] == '-') && (filename[1] == 0)) {
2247 f = stdin;
2248 } else {
William M. Brack3403add2004-06-27 02:07:51 +00002249#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2250 f = fopen(filename, "rb");
2251#else
2252 f = fopen(filename, "r");
2253#endif
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002254 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002255 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +00002256 int ret;
Daniel Veillarda880b122003-04-21 21:36:41 +00002257 int res, size = 1024;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002258 char chars[1024];
2259 xmlParserCtxtPtr ctxt;
2260
Daniel Veillarda880b122003-04-21 21:36:41 +00002261 /* if (repeat) size = 1024; */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002262 res = fread(chars, 1, 4, f);
2263 if (res > 0) {
2264 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
2265 chars, res, filename);
Daniel Veillard500a1de2004-03-22 15:22:58 +00002266 xmlCtxtUseOptions(ctxt, options);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002267 while ((res = fread(chars, 1, size, f)) > 0) {
2268 xmlParseChunk(ctxt, chars, res, 0);
2269 }
2270 xmlParseChunk(ctxt, chars, 0, 1);
2271 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +00002272 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002273 xmlFreeParserCtxt(ctxt);
Daniel Veillarde715dd22000-08-29 18:29:38 +00002274 if (!ret) {
2275 xmlFreeDoc(doc);
2276 doc = NULL;
2277 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002278 }
Daniel Veillard84bff682009-09-11 15:30:19 +02002279 if (f != stdin)
2280 fclose(f);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002281 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00002282 } else
2283#endif /* LIBXML_PUSH_ENABLED */
2284 if (testIO) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002285 if ((filename[0] == '-') && (filename[1] == 0)) {
Daniel Veillard60942de2003-09-25 21:05:58 +00002286 doc = xmlReadFd(0, NULL, NULL, options);
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002287 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002288 FILE *f;
Daniel Veillard5e873c42000-04-12 13:27:38 +00002289
William M. Brack3403add2004-06-27 02:07:51 +00002290#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2291 f = fopen(filename, "rb");
2292#else
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002293 f = fopen(filename, "r");
William M. Brack3403add2004-06-27 02:07:51 +00002294#endif
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002295 if (f != NULL) {
2296 if (rectxt == NULL)
2297 doc = xmlReadIO((xmlInputReadCallback) myRead,
2298 (xmlInputCloseCallback) myClose, f,
Daniel Veillard60942de2003-09-25 21:05:58 +00002299 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002300 else
2301 doc = xmlCtxtReadIO(rectxt,
2302 (xmlInputReadCallback) myRead,
2303 (xmlInputCloseCallback) myClose, f,
Daniel Veillard60942de2003-09-25 21:05:58 +00002304 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002305 } else
Daniel Veillard5e873c42000-04-12 13:27:38 +00002306 doc = NULL;
Daniel Veillard5e873c42000-04-12 13:27:38 +00002307 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002308 } else if (htmlout) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002309 xmlParserCtxtPtr ctxt;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002310
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002311 if (rectxt == NULL)
2312 ctxt = xmlNewParserCtxt();
2313 else
2314 ctxt = rectxt;
Daniel Veillardf1edb102009-08-10 14:43:18 +02002315 if (ctxt == NULL) {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002316 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +00002317 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002318 ctxt->sax->error = xmlHTMLError;
2319 ctxt->sax->warning = xmlHTMLWarning;
2320 ctxt->vctxt.error = xmlHTMLValidityError;
2321 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002322
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002323 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002324
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002325 if (rectxt == NULL)
2326 xmlFreeParserCtxt(ctxt);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002327 }
Daniel Veillard46e370e2000-07-21 20:32:03 +00002328#ifdef HAVE_SYS_MMAN_H
2329 } else if (memory) {
2330 int fd;
2331 struct stat info;
2332 const char *base;
Daniel Veillardf1edb102009-08-10 14:43:18 +02002333 if (stat(filename, &info) < 0)
Daniel Veillard46e370e2000-07-21 20:32:03 +00002334 return;
2335 if ((fd = open(filename, O_RDONLY)) < 0)
2336 return;
2337 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillard29579362000-08-14 17:57:48 +00002338 if (base == (void *) MAP_FAILED)
Daniel Veillard46e370e2000-07-21 20:32:03 +00002339 return;
2340
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002341 if (rectxt == NULL)
Daniel Veillard60942de2003-09-25 21:05:58 +00002342 doc = xmlReadMemory((char *) base, info.st_size,
2343 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002344 else
Daniel Veillard60942de2003-09-25 21:05:58 +00002345 doc = xmlCtxtReadMemory(rectxt, (char *) base, info.st_size,
2346 filename, NULL, options);
Daniel Veillardf1edb102009-08-10 14:43:18 +02002347
Daniel Veillard46e370e2000-07-21 20:32:03 +00002348 munmap((char *) base, info.st_size);
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002349 close(fd);
Daniel Veillard46e370e2000-07-21 20:32:03 +00002350#endif
Daniel Veillard4432df22003-09-28 18:58:27 +00002351#ifdef LIBXML_VALID_ENABLED
Daniel Veillardea7751d2002-12-20 00:16:24 +00002352 } else if (valid) {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002353 xmlParserCtxtPtr ctxt = NULL;
Daniel Veillardea7751d2002-12-20 00:16:24 +00002354
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002355 if (rectxt == NULL)
2356 ctxt = xmlNewParserCtxt();
2357 else
2358 ctxt = rectxt;
Daniel Veillardf1edb102009-08-10 14:43:18 +02002359 if (ctxt == NULL) {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002360 doc = NULL;
Daniel Veillardea7751d2002-12-20 00:16:24 +00002361 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002362 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
2363
2364 if (ctxt->valid == 0)
William M. Brack8304d872004-06-08 13:29:32 +00002365 progresult = XMLLINT_ERR_RDFILE;
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002366 if (rectxt == NULL)
2367 xmlFreeParserCtxt(ctxt);
Daniel Veillardea7751d2002-12-20 00:16:24 +00002368 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002369#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardea7751d2002-12-20 00:16:24 +00002370 } else {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002371 if (rectxt != NULL)
2372 doc = xmlCtxtReadFile(rectxt, filename, NULL, options);
Daniel Veillard81562d22005-06-15 13:27:56 +00002373 else {
2374#ifdef LIBXML_SAX1_ENABLED
2375 if (sax1)
2376 doc = xmlParseFile(filename);
2377 else
2378#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002379 doc = xmlReadFile(filename, NULL, options);
Daniel Veillard81562d22005-06-15 13:27:56 +00002380 }
Daniel Veillardea7751d2002-12-20 00:16:24 +00002381 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002382 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002383
Daniel Veillard88a172f2000-08-04 18:23:10 +00002384 /*
2385 * If we don't have a document we might as well give up. Do we
2386 * want an error message here? <sven@zen.org> */
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002387 if (doc == NULL) {
William M. Brack8304d872004-06-08 13:29:32 +00002388 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard88a172f2000-08-04 18:23:10 +00002389 return;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002390 }
2391
Daniel Veillard48b2f892001-02-25 16:11:03 +00002392 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002393 endTimer("Parsing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002394 }
2395
Daniel Veillard29e43992001-12-13 22:21:58 +00002396 /*
2397 * Remove DOCTYPE nodes
2398 */
2399 if (dropdtd) {
2400 xmlDtdPtr dtd;
2401
2402 dtd = xmlGetIntSubset(doc);
2403 if (dtd != NULL) {
2404 xmlUnlinkNode((xmlNodePtr)dtd);
2405 xmlFreeDtd(dtd);
2406 }
2407 }
2408
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002409#ifdef LIBXML_XINCLUDE_ENABLED
Daniel Veillard48b2f892001-02-25 16:11:03 +00002410 if (xinclude) {
2411 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002412 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002413 }
William M. Brack4e1c2db2005-02-11 10:58:55 +00002414 if (xmlXIncludeProcessFlags(doc, options) < 0)
2415 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard48b2f892001-02-25 16:11:03 +00002416 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002417 endTimer("Xinclude processing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002418 }
2419 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002420#endif
Daniel Veillard88a172f2000-08-04 18:23:10 +00002421
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002422#ifdef LIBXML_XPATH_ENABLED
2423 if (xpathquery != NULL) {
2424 doXPathQuery(doc, xpathquery);
2425 }
2426#endif
2427
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002428#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00002429#ifdef LIBXML_XPATH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002430 /*
Daniel Veillardcbaf3992001-12-31 16:16:02 +00002431 * shell interaction
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002432 */
Daniel Veillard26a45c82006-10-20 12:55:34 +00002433 if (shell) {
2434 xmlXPathOrderDocElems(doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002435 xmlShell(doc, filename, xmlShellReadline, stdout);
Daniel Veillard26a45c82006-10-20 12:55:34 +00002436 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002437#endif
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00002438#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002439
Daniel Veillard652327a2003-09-29 18:02:38 +00002440#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002441 /*
2442 * test intermediate copy if needed.
2443 */
2444 if (copy) {
2445 tmp = doc;
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002446 if (timing) {
2447 startTimer();
2448 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002449 doc = xmlCopyDoc(doc, 1);
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002450 if (timing) {
2451 endTimer("Copying");
2452 }
2453 if (timing) {
2454 startTimer();
2455 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002456 xmlFreeDoc(tmp);
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002457 if (timing) {
2458 endTimer("Freeing original");
2459 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002460 }
Daniel Veillard652327a2003-09-29 18:02:38 +00002461#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002462
Daniel Veillard4432df22003-09-28 18:58:27 +00002463#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002464 if ((insert) && (!html)) {
2465 const xmlChar* list[256];
2466 int nb, i;
2467 xmlNodePtr node;
2468
2469 if (doc->children != NULL) {
2470 node = doc->children;
2471 while ((node != NULL) && (node->last == NULL)) node = node->next;
2472 if (node != NULL) {
2473 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
2474 if (nb < 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002475 fprintf(stderr, "could not get valid list of elements\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002476 } else if (nb == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002477 fprintf(stderr, "No element can be inserted under root\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002478 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002479 fprintf(stderr, "%d element types can be inserted under root:\n",
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002480 nb);
2481 for (i = 0;i < nb;i++) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002482 fprintf(stderr, "%s\n", (char *) list[i]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002483 }
2484 }
2485 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02002486 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002487 }else
2488#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002489#ifdef LIBXML_READER_ENABLED
2490 if (walker) {
2491 walkDoc(doc);
2492 }
2493#endif /* LIBXML_READER_ENABLED */
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002494#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard4432df22003-09-28 18:58:27 +00002495 if (noout == 0) {
Daniel Veillard3df01182003-12-10 10:17:51 +00002496 int ret;
2497
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002498 /*
2499 * print it.
2500 */
2501#ifdef LIBXML_DEBUG_ENABLED
2502 if (!debug) {
2503#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00002504 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002505 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002506 }
Daniel Veillard656ce942004-04-30 23:11:45 +00002507#ifdef LIBXML_HTML_ENABLED
Daniel Veillard42fd4122003-11-04 08:47:48 +00002508 if ((html) && (!xmlout)) {
2509 if (compress) {
2510 htmlSaveFile(output ? output : "-", doc);
2511 }
2512 else if (encoding != NULL) {
2513 if ( format ) {
2514 htmlSaveFileFormat(output ? output : "-", doc, encoding, 1);
2515 }
2516 else {
2517 htmlSaveFileFormat(output ? output : "-", doc, encoding, 0);
2518 }
2519 }
2520 else if (format) {
2521 htmlSaveFileFormat(output ? output : "-", doc, NULL, 1);
2522 }
2523 else {
2524 FILE *out;
2525 if (output == NULL)
2526 out = stdout;
2527 else {
2528 out = fopen(output,"wb");
2529 }
2530 if (out != NULL) {
2531 if (htmlDocDump(out, doc) < 0)
William M. Brack8304d872004-06-08 13:29:32 +00002532 progresult = XMLLINT_ERR_OUT;
Daniel Veillard42fd4122003-11-04 08:47:48 +00002533
2534 if (output != NULL)
2535 fclose(out);
2536 } else {
2537 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00002538 progresult = XMLLINT_ERR_OUT;
Daniel Veillard42fd4122003-11-04 08:47:48 +00002539 }
2540 }
2541 if ((timing) && (!repeat)) {
2542 endTimer("Saving");
2543 }
2544 } else
2545#endif
Daniel Veillard25048d82004-08-14 22:37:54 +00002546#ifdef LIBXML_C14N_ENABLED
2547 if (canonical) {
2548 xmlChar *result = NULL;
2549 int size;
2550
Aleksey Sanin83868242009-07-09 10:26:22 +02002551 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_0, NULL, 1, &result);
2552 if (size >= 0) {
2553 write(1, result, size);
2554 xmlFree(result);
2555 } else {
2556 fprintf(stderr, "Failed to canonicalize\n");
2557 progresult = XMLLINT_ERR_OUT;
2558 }
2559 } else if (canonical) {
2560 xmlChar *result = NULL;
2561 int size;
2562
2563 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_1, NULL, 1, &result);
Daniel Veillard25048d82004-08-14 22:37:54 +00002564 if (size >= 0) {
2565 write(1, result, size);
2566 xmlFree(result);
2567 } else {
2568 fprintf(stderr, "Failed to canonicalize\n");
2569 progresult = XMLLINT_ERR_OUT;
2570 }
2571 } else
Aleksey Sanin2650df12005-06-06 17:16:50 +00002572 if (exc_canonical) {
2573 xmlChar *result = NULL;
2574 int size;
2575
Aleksey Sanin83868242009-07-09 10:26:22 +02002576 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_EXCLUSIVE_1_0, NULL, 1, &result);
Aleksey Sanin2650df12005-06-06 17:16:50 +00002577 if (size >= 0) {
2578 write(1, result, size);
2579 xmlFree(result);
2580 } else {
2581 fprintf(stderr, "Failed to canonicalize\n");
2582 progresult = XMLLINT_ERR_OUT;
2583 }
2584 } else
Daniel Veillard25048d82004-08-14 22:37:54 +00002585#endif
Daniel Veillard3b2c2612001-04-04 00:09:00 +00002586#ifdef HAVE_SYS_MMAN_H
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002587 if (memory) {
2588 xmlChar *result;
2589 int len;
2590
2591 if (encoding != NULL) {
Daniel Veillardd536f702001-11-08 17:32:47 +00002592 if ( format ) {
2593 xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
Daniel Veillardf1edb102009-08-10 14:43:18 +02002594 } else {
Daniel Veillardd536f702001-11-08 17:32:47 +00002595 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
2596 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002597 } else {
Daniel Veillard90493a92001-08-14 14:12:47 +00002598 if (format)
2599 xmlDocDumpFormatMemory(doc, &result, &len, 1);
2600 else
2601 xmlDocDumpMemory(doc, &result, &len);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002602 }
2603 if (result == NULL) {
2604 fprintf(stderr, "Failed to save\n");
Daniel Veillard25048d82004-08-14 22:37:54 +00002605 progresult = XMLLINT_ERR_OUT;
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002606 } else {
2607 write(1, result, len);
2608 xmlFree(result);
2609 }
Daniel Veillarddab39b52006-10-16 23:22:10 +00002610
Daniel Veillard3b2c2612001-04-04 00:09:00 +00002611 } else
2612#endif /* HAVE_SYS_MMAN_H */
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002613 if (compress) {
2614 xmlSaveFile(output ? output : "-", doc);
Daniel Veillarddab39b52006-10-16 23:22:10 +00002615 } else if (oldout) {
2616 if (encoding != NULL) {
2617 if ( format ) {
2618 ret = xmlSaveFormatFileEnc(output ? output : "-", doc,
2619 encoding, 1);
2620 }
2621 else {
2622 ret = xmlSaveFileEnc(output ? output : "-", doc,
2623 encoding);
2624 }
2625 if (ret < 0) {
2626 fprintf(stderr, "failed save to %s\n",
2627 output ? output : "-");
2628 progresult = XMLLINT_ERR_OUT;
2629 }
2630 } else if (format) {
2631 ret = xmlSaveFormatFile(output ? output : "-", doc, 1);
2632 if (ret < 0) {
2633 fprintf(stderr, "failed save to %s\n",
2634 output ? output : "-");
2635 progresult = XMLLINT_ERR_OUT;
2636 }
Daniel Veillard05d987b2003-10-08 11:54:57 +00002637 } else {
Daniel Veillarddab39b52006-10-16 23:22:10 +00002638 FILE *out;
2639 if (output == NULL)
2640 out = stdout;
2641 else {
2642 out = fopen(output,"wb");
2643 }
2644 if (out != NULL) {
2645 if (xmlDocDump(out, doc) < 0)
2646 progresult = XMLLINT_ERR_OUT;
2647
2648 if (output != NULL)
2649 fclose(out);
2650 } else {
2651 fprintf(stderr, "failed to open %s\n", output);
2652 progresult = XMLLINT_ERR_OUT;
2653 }
2654 }
2655 } else {
2656 xmlSaveCtxtPtr ctxt;
2657 int saveOpts = 0;
2658
2659 if (format)
2660 saveOpts |= XML_SAVE_FORMAT;
Daniel Veillard9ccea572010-03-10 15:02:49 +01002661
2662#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
Daniel Veillard9d962642009-08-23 15:31:18 +02002663 if (xmlout)
2664 saveOpts |= XML_SAVE_AS_XML;
Daniel Veillard9ccea572010-03-10 15:02:49 +01002665#endif
Daniel Veillarddab39b52006-10-16 23:22:10 +00002666
2667 if (output == NULL)
2668 ctxt = xmlSaveToFd(1, encoding, saveOpts);
2669 else
2670 ctxt = xmlSaveToFilename(output, encoding, saveOpts);
2671
2672 if (ctxt != NULL) {
2673 if (xmlSaveDoc(ctxt, doc) < 0) {
2674 fprintf(stderr, "failed save to %s\n",
2675 output ? output : "-");
2676 progresult = XMLLINT_ERR_OUT;
2677 }
2678 xmlSaveClose(ctxt);
2679 } else {
William M. Brack8304d872004-06-08 13:29:32 +00002680 progresult = XMLLINT_ERR_OUT;
Daniel Veillard05d987b2003-10-08 11:54:57 +00002681 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002682 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002683 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002684 endTimer("Saving");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002685 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002686#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002687 } else {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002688 FILE *out;
2689 if (output == NULL)
2690 out = stdout;
2691 else {
2692 out = fopen(output,"wb");
2693 }
Daniel Veillard05d987b2003-10-08 11:54:57 +00002694 if (out != NULL) {
2695 xmlDebugDumpDocument(out, doc);
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002696
Daniel Veillard05d987b2003-10-08 11:54:57 +00002697 if (output != NULL)
2698 fclose(out);
2699 } else {
2700 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00002701 progresult = XMLLINT_ERR_OUT;
Daniel Veillard05d987b2003-10-08 11:54:57 +00002702 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002703 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002704#endif
2705 }
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002706#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002707
Daniel Veillard4432df22003-09-28 18:58:27 +00002708#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002709 /*
2710 * A posteriori validation test
2711 */
Daniel Veillard66f68e72003-08-18 16:39:51 +00002712 if ((dtdvalid != NULL) || (dtdvalidfpi != NULL)) {
Daniel Veillardcd429612000-10-11 15:57:05 +00002713 xmlDtdPtr dtd;
2714
Daniel Veillard48b2f892001-02-25 16:11:03 +00002715 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002716 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002717 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00002718 if (dtdvalid != NULL)
Daniel Veillardf1edb102009-08-10 14:43:18 +02002719 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
Daniel Veillard66f68e72003-08-18 16:39:51 +00002720 else
Daniel Veillardf1edb102009-08-10 14:43:18 +02002721 dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL);
Daniel Veillard48b2f892001-02-25 16:11:03 +00002722 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002723 endTimer("Parsing DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002724 }
Daniel Veillardcd429612000-10-11 15:57:05 +00002725 if (dtd == NULL) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00002726 if (dtdvalid != NULL)
2727 xmlGenericError(xmlGenericErrorContext,
2728 "Could not parse DTD %s\n", dtdvalid);
2729 else
2730 xmlGenericError(xmlGenericErrorContext,
2731 "Could not parse DTD %s\n", dtdvalidfpi);
William M. Brack8304d872004-06-08 13:29:32 +00002732 progresult = XMLLINT_ERR_DTD;
Daniel Veillardcd429612000-10-11 15:57:05 +00002733 } else {
Daniel Veillarda37aab82003-06-09 09:10:36 +00002734 xmlValidCtxtPtr cvp;
2735
2736 if ((cvp = xmlNewValidCtxt()) == NULL) {
2737 xmlGenericError(xmlGenericErrorContext,
2738 "Couldn't allocate validation context\n");
2739 exit(-1);
2740 }
2741 cvp->userData = (void *) stderr;
2742 cvp->error = (xmlValidityErrorFunc) fprintf;
2743 cvp->warning = (xmlValidityWarningFunc) fprintf;
2744
Daniel Veillard48b2f892001-02-25 16:11:03 +00002745 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002746 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002747 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002748 if (!xmlValidateDtd(cvp, doc, dtd)) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00002749 if (dtdvalid != NULL)
2750 xmlGenericError(xmlGenericErrorContext,
2751 "Document %s does not validate against %s\n",
2752 filename, dtdvalid);
2753 else
2754 xmlGenericError(xmlGenericErrorContext,
2755 "Document %s does not validate against %s\n",
2756 filename, dtdvalidfpi);
William M. Brack8304d872004-06-08 13:29:32 +00002757 progresult = XMLLINT_ERR_VALID;
Daniel Veillardcd429612000-10-11 15:57:05 +00002758 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002759 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002760 endTimer("Validating against DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002761 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002762 xmlFreeValidCtxt(cvp);
Daniel Veillardcd429612000-10-11 15:57:05 +00002763 xmlFreeDtd(dtd);
2764 }
2765 } else if (postvalid) {
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
Daniel Veillard48b2f892001-02-25 16:11:03 +00002774 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002775 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002776 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002777 cvp->userData = (void *) stderr;
2778 cvp->error = (xmlValidityErrorFunc) fprintf;
2779 cvp->warning = (xmlValidityWarningFunc) fprintf;
2780 if (!xmlValidateDocument(cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00002781 xmlGenericError(xmlGenericErrorContext,
2782 "Document %s does not validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002783 progresult = XMLLINT_ERR_VALID;
Daniel Veillardcd429612000-10-11 15:57:05 +00002784 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002785 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002786 endTimer("Validating");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002787 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002788 xmlFreeValidCtxt(cvp);
Daniel Veillard4432df22003-09-28 18:58:27 +00002789 }
2790#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardd4501d72005-07-24 14:27:16 +00002791#ifdef LIBXML_SCHEMATRON_ENABLED
2792 if (wxschematron != NULL) {
2793 xmlSchematronValidCtxtPtr ctxt;
2794 int ret;
Daniel Veillardc740a172005-07-31 12:17:24 +00002795 int flag;
Daniel Veillardd4501d72005-07-24 14:27:16 +00002796
2797 if ((timing) && (!repeat)) {
2798 startTimer();
2799 }
2800
2801 if (debug)
2802 flag = XML_SCHEMATRON_OUT_XML;
Daniel Veillardc740a172005-07-31 12:17:24 +00002803 else
2804 flag = XML_SCHEMATRON_OUT_TEXT;
2805 if (noout)
2806 flag |= XML_SCHEMATRON_OUT_QUIET;
Daniel Veillardd4501d72005-07-24 14:27:16 +00002807 ctxt = xmlSchematronNewValidCtxt(wxschematron, flag);
2808#if 0
2809 xmlSchematronSetValidErrors(ctxt,
2810 (xmlSchematronValidityErrorFunc) fprintf,
2811 (xmlSchematronValidityWarningFunc) fprintf,
2812 stderr);
2813#endif
2814 ret = xmlSchematronValidateDoc(ctxt, doc);
2815 if (ret == 0) {
2816 fprintf(stderr, "%s validates\n", filename);
2817 } else if (ret > 0) {
2818 fprintf(stderr, "%s fails to validate\n", filename);
2819 progresult = XMLLINT_ERR_VALID;
2820 } else {
2821 fprintf(stderr, "%s validation generated an internal error\n",
2822 filename);
2823 progresult = XMLLINT_ERR_VALID;
2824 }
2825 xmlSchematronFreeValidCtxt(ctxt);
2826 if ((timing) && (!repeat)) {
2827 endTimer("Validating");
2828 }
2829 }
2830#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00002831#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard4432df22003-09-28 18:58:27 +00002832 if (relaxngschemas != NULL) {
Daniel Veillard71531f32003-02-05 13:19:53 +00002833 xmlRelaxNGValidCtxtPtr ctxt;
2834 int ret;
2835
Daniel Veillard42f12e92003-03-07 18:32:59 +00002836 if ((timing) && (!repeat)) {
2837 startTimer();
2838 }
2839
Daniel Veillard71531f32003-02-05 13:19:53 +00002840 ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
2841 xmlRelaxNGSetValidErrors(ctxt,
2842 (xmlRelaxNGValidityErrorFunc) fprintf,
2843 (xmlRelaxNGValidityWarningFunc) fprintf,
2844 stderr);
2845 ret = xmlRelaxNGValidateDoc(ctxt, doc);
2846 if (ret == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002847 fprintf(stderr, "%s validates\n", filename);
Daniel Veillard71531f32003-02-05 13:19:53 +00002848 } else if (ret > 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002849 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002850 progresult = XMLLINT_ERR_VALID;
Daniel Veillard71531f32003-02-05 13:19:53 +00002851 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002852 fprintf(stderr, "%s validation generated an internal error\n",
Daniel Veillard71531f32003-02-05 13:19:53 +00002853 filename);
William M. Brack8304d872004-06-08 13:29:32 +00002854 progresult = XMLLINT_ERR_VALID;
Daniel Veillard71531f32003-02-05 13:19:53 +00002855 }
2856 xmlRelaxNGFreeValidCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00002857 if ((timing) && (!repeat)) {
2858 endTimer("Validating");
2859 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002860 } else if (wxschemas != NULL) {
2861 xmlSchemaValidCtxtPtr ctxt;
2862 int ret;
2863
2864 if ((timing) && (!repeat)) {
2865 startTimer();
2866 }
2867
2868 ctxt = xmlSchemaNewValidCtxt(wxschemas);
2869 xmlSchemaSetValidErrors(ctxt,
2870 (xmlSchemaValidityErrorFunc) fprintf,
2871 (xmlSchemaValidityWarningFunc) fprintf,
2872 stderr);
2873 ret = xmlSchemaValidateDoc(ctxt, doc);
2874 if (ret == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002875 fprintf(stderr, "%s validates\n", filename);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002876 } else if (ret > 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002877 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002878 progresult = XMLLINT_ERR_VALID;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002879 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002880 fprintf(stderr, "%s validation generated an internal error\n",
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002881 filename);
William M. Brack8304d872004-06-08 13:29:32 +00002882 progresult = XMLLINT_ERR_VALID;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002883 }
2884 xmlSchemaFreeValidCtxt(ctxt);
2885 if ((timing) && (!repeat)) {
2886 endTimer("Validating");
2887 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002888 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002889#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002890
2891#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillard6b099012008-11-06 13:47:39 +00002892#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002893 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00002894 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002895#endif
Daniel Veillard6b099012008-11-06 13:47:39 +00002896#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002897
2898 /*
2899 * free it.
2900 */
Daniel Veillard48b2f892001-02-25 16:11:03 +00002901 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002902 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002903 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002904 xmlFreeDoc(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +00002905 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002906 endTimer("Freeing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002907 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002908}
2909
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002910/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +02002911 * *
2912 * Usage and Main *
2913 * *
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002914 ************************************************************************/
2915
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002916static void showVersion(const char *name) {
2917 fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
2918 fprintf(stderr, " compiled with: ");
Daniel Veillard602434d2005-09-12 09:20:31 +00002919 if (xmlHasFeature(XML_WITH_THREAD)) fprintf(stderr, "Threads ");
2920 if (xmlHasFeature(XML_WITH_TREE)) fprintf(stderr, "Tree ");
2921 if (xmlHasFeature(XML_WITH_OUTPUT)) fprintf(stderr, "Output ");
2922 if (xmlHasFeature(XML_WITH_PUSH)) fprintf(stderr, "Push ");
2923 if (xmlHasFeature(XML_WITH_READER)) fprintf(stderr, "Reader ");
2924 if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(stderr, "Patterns ");
2925 if (xmlHasFeature(XML_WITH_WRITER)) fprintf(stderr, "Writer ");
2926 if (xmlHasFeature(XML_WITH_SAX1)) fprintf(stderr, "SAXv1 ");
Daniel Veillardf1edb102009-08-10 14:43:18 +02002927 if (xmlHasFeature(XML_WITH_FTP)) fprintf(stderr, "FTP ");
2928 if (xmlHasFeature(XML_WITH_HTTP)) fprintf(stderr, "HTTP ");
Daniel Veillard602434d2005-09-12 09:20:31 +00002929 if (xmlHasFeature(XML_WITH_VALID)) fprintf(stderr, "DTDValid ");
Daniel Veillardf1edb102009-08-10 14:43:18 +02002930 if (xmlHasFeature(XML_WITH_HTML)) fprintf(stderr, "HTML ");
2931 if (xmlHasFeature(XML_WITH_LEGACY)) fprintf(stderr, "Legacy ");
2932 if (xmlHasFeature(XML_WITH_C14N)) fprintf(stderr, "C14N ");
2933 if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(stderr, "Catalog ");
2934 if (xmlHasFeature(XML_WITH_XPATH)) fprintf(stderr, "XPath ");
2935 if (xmlHasFeature(XML_WITH_XPTR)) fprintf(stderr, "XPointer ");
2936 if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(stderr, "XInclude ");
2937 if (xmlHasFeature(XML_WITH_ICONV)) fprintf(stderr, "Iconv ");
2938 if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(stderr, "ISO8859X ");
2939 if (xmlHasFeature(XML_WITH_UNICODE)) fprintf(stderr, "Unicode ");
2940 if (xmlHasFeature(XML_WITH_REGEXP)) fprintf(stderr, "Regexps ");
2941 if (xmlHasFeature(XML_WITH_AUTOMATA)) fprintf(stderr, "Automata ");
2942 if (xmlHasFeature(XML_WITH_EXPR)) fprintf(stderr, "Expr ");
2943 if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(stderr, "Schemas ");
2944 if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(stderr, "Schematron ");
2945 if (xmlHasFeature(XML_WITH_MODULES)) fprintf(stderr, "Modules ");
2946 if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(stderr, "Debug ");
2947 if (xmlHasFeature(XML_WITH_DEBUG_MEM)) fprintf(stderr, "MemDebug ");
2948 if (xmlHasFeature(XML_WITH_DEBUG_RUN)) fprintf(stderr, "RunDebug ");
Daniel Veillard75acfee2006-07-13 06:29:56 +00002949 if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(stderr, "Zlib ");
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002950 fprintf(stderr, "\n");
2951}
2952
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002953static void usage(const char *name) {
2954 printf("Usage : %s [options] XMLfiles ...\n", name);
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002955#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002956 printf("\tParse the XML files and output the result of the parsing\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002957#else
2958 printf("\tParse the XML files\n");
2959#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002960 printf("\t--version : display the version of the XML library used\n");
2961#ifdef LIBXML_DEBUG_ENABLED
2962 printf("\t--debug : dump a debug tree of the in-memory document\n");
2963 printf("\t--shell : run a navigating shell\n");
2964 printf("\t--debugent : debug the entities defined in the document\n");
Daniel Veillard8326e732003-01-07 00:19:07 +00002965#else
Daniel Veillard81273902003-09-30 00:43:48 +00002966#ifdef LIBXML_READER_ENABLED
Daniel Veillard8326e732003-01-07 00:19:07 +00002967 printf("\t--debug : dump the nodes content when using --stream\n");
Daniel Veillard81273902003-09-30 00:43:48 +00002968#endif /* LIBXML_READER_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002969#endif
Daniel Veillard652327a2003-09-29 18:02:38 +00002970#ifdef LIBXML_TREE_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002971 printf("\t--copy : used to test the internal copy implementation\n");
Daniel Veillard652327a2003-09-29 18:02:38 +00002972#endif /* LIBXML_TREE_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002973 printf("\t--recover : output what was parsable on broken XML documents\n");
Daniel Veillard8915c152008-08-26 13:05:34 +00002974 printf("\t--huge : remove any internal arbitrary parser limits\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002975 printf("\t--noent : substitute entity references by their value\n");
2976 printf("\t--noout : don't output the result tree\n");
Daniel Veillard0bff36d2004-08-31 09:37:03 +00002977 printf("\t--path 'paths': provide a set of paths for resources\n");
2978 printf("\t--load-trace : print trace of all external entites loaded\n");
Daniel Veillarde8b09e42003-05-13 22:14:13 +00002979 printf("\t--nonet : refuse to fetch DTDs or entities over network\n");
Daniel Veillard8874b942005-08-25 13:19:21 +00002980 printf("\t--nocompact : do not generate compact text nodes\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002981 printf("\t--htmlout : output results as HTML\n");
Daniel Veillard05c13a22001-09-09 08:38:09 +00002982 printf("\t--nowrap : do not put HTML doc wrapper\n");
Daniel Veillard4432df22003-09-28 18:58:27 +00002983#ifdef LIBXML_VALID_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002984 printf("\t--valid : validate the document in addition to std well-formed check\n");
2985 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
2986 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
Daniel Veillard66f68e72003-08-18 16:39:51 +00002987 printf("\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
Daniel Veillard4432df22003-09-28 18:58:27 +00002988#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002989 printf("\t--timing : print some timings\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002990 printf("\t--output file or -o file: save to a given file\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002991 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
2992 printf("\t--insert : ad-hoc test for valid insertions\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002993#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002994#ifdef HAVE_ZLIB_H
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002995 printf("\t--compress : turn on gzip compression of output\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002996#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002997#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002998#ifdef LIBXML_HTML_ENABLED
2999 printf("\t--html : use the HTML parser\n");
Daniel Veillard42fd4122003-11-04 08:47:48 +00003000 printf("\t--xmlout : force to use the XML serializer when using --html\n");
Daniel Veillardf1121c42010-07-26 14:02:42 +02003001 printf("\t--nodefdtd : do not default HTML doctype\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003002#endif
Daniel Veillard73b013f2003-09-30 12:36:01 +00003003#ifdef LIBXML_PUSH_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003004 printf("\t--push : use the push mode of the parser\n");
Daniel Veillard73b013f2003-09-30 12:36:01 +00003005#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003006#ifdef HAVE_SYS_MMAN_H
3007 printf("\t--memory : parse from memory\n");
3008#endif
Daniel Veillard87076042004-05-03 22:54:49 +00003009 printf("\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003010 printf("\t--nowarning : do not emit warnings from parser/validator\n");
3011 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
Daniel Veillarddca8cc72003-09-26 13:53:14 +00003012 printf("\t--nocdata : replace cdata section with text nodes\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003013#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard90493a92001-08-14 14:12:47 +00003014 printf("\t--format : reformat/reindent the input\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003015 printf("\t--encode encoding : output in the given encoding\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003016 printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
3017#endif /* LIBXML_OUTPUT_ENABLED */
Aleksey Sanin83868242009-07-09 10:26:22 +02003018 printf("\t--c14n : save in W3C canonical format v1.0 (with comments)\n");
3019 printf("\t--c14n11 : save in W3C canonical format v1.1 (with comments)\n");
Aleksey Sanin2650df12005-06-06 17:16:50 +00003020 printf("\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n");
Daniel Veillard25048d82004-08-14 22:37:54 +00003021#ifdef LIBXML_C14N_ENABLED
3022#endif /* LIBXML_C14N_ENABLED */
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003023 printf("\t--nsclean : remove redundant namespace declarations\n");
3024 printf("\t--testIO : test user I/O support\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003025#ifdef LIBXML_CATALOG_ENABLED
Daniel Veillardbd9b0e82001-11-26 10:32:08 +00003026 printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
3027 printf("\t otherwise XML Catalogs starting from \n");
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003028 printf("\t %s are activated by default\n", XML_XML_DEFAULT_CATALOG);
Daniel Veillard05c13a22001-09-09 08:38:09 +00003029 printf("\t--nocatalogs: deactivate all catalogs\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003030#endif
3031 printf("\t--auto : generate a small doc on the fly\n");
3032#ifdef LIBXML_XINCLUDE_ENABLED
3033 printf("\t--xinclude : do XInclude processing\n");
Daniel Veillardc14c3892004-08-16 12:34:50 +00003034 printf("\t--noxincludenode : same but do not generate XInclude nodes\n");
Daniel Veillard54bd29b2008-08-26 07:26:55 +00003035 printf("\t--nofixup-base-uris : do not fixup xml:base uris\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003036#endif
Daniel Veillardcbaf3992001-12-31 16:16:02 +00003037 printf("\t--loaddtd : fetch external DTD\n");
Daniel Veillard48da9102001-08-07 01:10:10 +00003038 printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
Daniel Veillard81273902003-09-30 00:43:48 +00003039#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003040 printf("\t--stream : use the streaming interface to process very large files\n");
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003041 printf("\t--walker : create a reader and walk though the resulting doc\n");
Daniel Veillard81273902003-09-30 00:43:48 +00003042#endif /* LIBXML_READER_ENABLED */
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003043#ifdef LIBXML_PATTERN_ENABLED
3044 printf("\t--pattern pattern_value : test the pattern support\n");
3045#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003046 printf("\t--chkregister : verify the node registration code\n");
Daniel Veillardef4d3bc2003-02-07 12:38:22 +00003047#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard71531f32003-02-05 13:19:53 +00003048 printf("\t--relaxng schema : do RelaxNG validation against the schema\n");
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003049 printf("\t--schema schema : do validation against the WXS schema\n");
Daniel Veillard71531f32003-02-05 13:19:53 +00003050#endif
Daniel Veillarde70375c2005-07-30 21:09:12 +00003051#ifdef LIBXML_SCHEMATRON_ENABLED
3052 printf("\t--schematron schema : do validation against a schematron\n");
3053#endif
Daniel Veillard971771e2005-07-09 17:32:57 +00003054#ifdef LIBXML_SAX1_ENABLED
3055 printf("\t--sax1: use the old SAX1 interfaces for processing\n");
3056#endif
3057 printf("\t--sax: do not build a tree but work just at the SAX level\n");
Daniel Veillard7e5c3f42008-07-29 16:12:31 +00003058 printf("\t--oldxml10: use XML-1.0 parsing rules before the 5th edition\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003059#ifdef LIBXML_XPATH_ENABLED
3060 printf("\t--xpath expr: evaluate the XPath expression, inply --noout\n");
3061#endif
Daniel Veillard971771e2005-07-09 17:32:57 +00003062
Daniel Veillarda42f25f2002-01-25 14:15:40 +00003063 printf("\nLibxml project home page: http://xmlsoft.org/\n");
3064 printf("To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003065}
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003066
3067static void registerNode(xmlNodePtr node)
3068{
3069 node->_private = malloc(sizeof(long));
3070 *(long*)node->_private = (long) 0x81726354;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003071 nbregister++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003072}
3073
3074static void deregisterNode(xmlNodePtr node)
3075{
3076 assert(node->_private != NULL);
3077 assert(*(long*)node->_private == (long) 0x81726354);
3078 free(node->_private);
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003079 nbregister--;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003080}
3081
Daniel Veillard4a6845d2001-01-03 13:32:39 +00003082int
3083main(int argc, char **argv) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00003084 int i, acount;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003085 int files = 0;
Daniel Veillard845cce42002-01-09 11:51:37 +00003086 int version = 0;
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00003087 const char* indent;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003088
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003089 if (argc <= 1) {
3090 usage(argv[0]);
3091 return(1);
3092 }
Daniel Veillardbe803962000-06-28 23:40:59 +00003093 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003094 for (i = 1; i < argc ; i++) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003095 if (!strcmp(argv[i], "-"))
3096 break;
3097
3098 if (argv[i][0] != '-')
3099 continue;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003100 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
3101 debug++;
Daniel Veillard56ada1d2003-01-07 11:17:25 +00003102 else
3103#ifdef LIBXML_DEBUG_ENABLED
3104 if ((!strcmp(argv[i], "-shell")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003105 (!strcmp(argv[i], "--shell"))) {
3106 shell++;
3107 noout = 1;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003108 } else
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003109#endif
Daniel Veillard652327a2003-09-29 18:02:38 +00003110#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003111 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
3112 copy++;
Daniel Veillard652327a2003-09-29 18:02:38 +00003113 else
3114#endif /* LIBXML_TREE_ENABLED */
3115 if ((!strcmp(argv[i], "-recover")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003116 (!strcmp(argv[i], "--recover"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003117 recovery++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003118 options |= XML_PARSE_RECOVER;
Daniel Veillard8915c152008-08-26 13:05:34 +00003119 } else if ((!strcmp(argv[i], "-huge")) ||
3120 (!strcmp(argv[i], "--huge"))) {
3121 options |= XML_PARSE_HUGE;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003122 } else if ((!strcmp(argv[i], "-noent")) ||
3123 (!strcmp(argv[i], "--noent"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003124 noent++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003125 options |= XML_PARSE_NOENT;
Daniel Veillarddca8cc72003-09-26 13:53:14 +00003126 } else if ((!strcmp(argv[i], "-nsclean")) ||
3127 (!strcmp(argv[i], "--nsclean"))) {
3128 options |= XML_PARSE_NSCLEAN;
3129 } else if ((!strcmp(argv[i], "-nocdata")) ||
3130 (!strcmp(argv[i], "--nocdata"))) {
3131 options |= XML_PARSE_NOCDATA;
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003132 } else if ((!strcmp(argv[i], "-nodict")) ||
3133 (!strcmp(argv[i], "--nodict"))) {
3134 options |= XML_PARSE_NODICT;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003135 } else if ((!strcmp(argv[i], "-version")) ||
Daniel Veillard845cce42002-01-09 11:51:37 +00003136 (!strcmp(argv[i], "--version"))) {
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00003137 showVersion(argv[0]);
Daniel Veillard845cce42002-01-09 11:51:37 +00003138 version = 1;
3139 } else if ((!strcmp(argv[i], "-noout")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003140 (!strcmp(argv[i], "--noout")))
3141 noout++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003142#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003143 else if ((!strcmp(argv[i], "-o")) ||
3144 (!strcmp(argv[i], "-output")) ||
3145 (!strcmp(argv[i], "--output"))) {
3146 i++;
Daniel Veillard6e4f1c02002-04-09 09:55:20 +00003147 output = argv[i];
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003148 }
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003149#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003150 else if ((!strcmp(argv[i], "-htmlout")) ||
3151 (!strcmp(argv[i], "--htmlout")))
3152 htmlout++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003153 else if ((!strcmp(argv[i], "-nowrap")) ||
3154 (!strcmp(argv[i], "--nowrap")))
3155 nowrap++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003156#ifdef LIBXML_HTML_ENABLED
3157 else if ((!strcmp(argv[i], "-html")) ||
3158 (!strcmp(argv[i], "--html"))) {
3159 html++;
3160 }
Daniel Veillard42fd4122003-11-04 08:47:48 +00003161 else if ((!strcmp(argv[i], "-xmlout")) ||
3162 (!strcmp(argv[i], "--xmlout"))) {
3163 xmlout++;
Daniel Veillardf1121c42010-07-26 14:02:42 +02003164 } else if ((!strcmp(argv[i], "-nodefdtd")) ||
3165 (!strcmp(argv[i], "--nodefdtd"))) {
3166 nodefdtd++;
3167 options |= HTML_PARSE_NODEFDTD;
Daniel Veillard42fd4122003-11-04 08:47:48 +00003168 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003169#endif /* LIBXML_HTML_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003170 else if ((!strcmp(argv[i], "-loaddtd")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003171 (!strcmp(argv[i], "--loaddtd"))) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003172 loaddtd++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003173 options |= XML_PARSE_DTDLOAD;
3174 } else if ((!strcmp(argv[i], "-dtdattr")) ||
Daniel Veillard48da9102001-08-07 01:10:10 +00003175 (!strcmp(argv[i], "--dtdattr"))) {
3176 loaddtd++;
3177 dtdattrs++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003178 options |= XML_PARSE_DTDATTR;
Daniel Veillard4432df22003-09-28 18:58:27 +00003179 }
3180#ifdef LIBXML_VALID_ENABLED
3181 else if ((!strcmp(argv[i], "-valid")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003182 (!strcmp(argv[i], "--valid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003183 valid++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003184 options |= XML_PARSE_DTDVALID;
3185 } else if ((!strcmp(argv[i], "-postvalid")) ||
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003186 (!strcmp(argv[i], "--postvalid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003187 postvalid++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003188 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003189 options |= XML_PARSE_DTDLOAD;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003190 } else if ((!strcmp(argv[i], "-dtdvalid")) ||
Daniel Veillardcd429612000-10-11 15:57:05 +00003191 (!strcmp(argv[i], "--dtdvalid"))) {
3192 i++;
3193 dtdvalid = argv[i];
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003194 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003195 options |= XML_PARSE_DTDLOAD;
Daniel Veillard66f68e72003-08-18 16:39:51 +00003196 } else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3197 (!strcmp(argv[i], "--dtdvalidfpi"))) {
3198 i++;
3199 dtdvalidfpi = argv[i];
3200 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003201 options |= XML_PARSE_DTDLOAD;
Daniel Veillardcd429612000-10-11 15:57:05 +00003202 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003203#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard29e43992001-12-13 22:21:58 +00003204 else if ((!strcmp(argv[i], "-dropdtd")) ||
3205 (!strcmp(argv[i], "--dropdtd")))
3206 dropdtd++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003207 else if ((!strcmp(argv[i], "-insert")) ||
3208 (!strcmp(argv[i], "--insert")))
3209 insert++;
Daniel Veillard48b2f892001-02-25 16:11:03 +00003210 else if ((!strcmp(argv[i], "-timing")) ||
3211 (!strcmp(argv[i], "--timing")))
3212 timing++;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00003213 else if ((!strcmp(argv[i], "-auto")) ||
3214 (!strcmp(argv[i], "--auto")))
3215 generate++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003216 else if ((!strcmp(argv[i], "-repeat")) ||
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00003217 (!strcmp(argv[i], "--repeat"))) {
3218 if (repeat)
3219 repeat *= 10;
3220 else
3221 repeat = 100;
Daniel Veillard73b013f2003-09-30 12:36:01 +00003222 }
3223#ifdef LIBXML_PUSH_ENABLED
3224 else if ((!strcmp(argv[i], "-push")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003225 (!strcmp(argv[i], "--push")))
3226 push++;
Daniel Veillard73b013f2003-09-30 12:36:01 +00003227#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillard46e370e2000-07-21 20:32:03 +00003228#ifdef HAVE_SYS_MMAN_H
3229 else if ((!strcmp(argv[i], "-memory")) ||
3230 (!strcmp(argv[i], "--memory")))
3231 memory++;
3232#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +00003233 else if ((!strcmp(argv[i], "-testIO")) ||
3234 (!strcmp(argv[i], "--testIO")))
3235 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003236#ifdef LIBXML_XINCLUDE_ENABLED
3237 else if ((!strcmp(argv[i], "-xinclude")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003238 (!strcmp(argv[i], "--xinclude"))) {
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003239 xinclude++;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003240 options |= XML_PARSE_XINCLUDE;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003241 }
Daniel Veillardc14c3892004-08-16 12:34:50 +00003242 else if ((!strcmp(argv[i], "-noxincludenode")) ||
3243 (!strcmp(argv[i], "--noxincludenode"))) {
3244 xinclude++;
3245 options |= XML_PARSE_XINCLUDE;
3246 options |= XML_PARSE_NOXINCNODE;
3247 }
Daniel Veillard54bd29b2008-08-26 07:26:55 +00003248 else if ((!strcmp(argv[i], "-nofixup-base-uris")) ||
3249 (!strcmp(argv[i], "--nofixup-base-uris"))) {
3250 xinclude++;
3251 options |= XML_PARSE_XINCLUDE;
3252 options |= XML_PARSE_NOBASEFIX;
3253 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003254#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003255#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003256#ifdef HAVE_ZLIB_H
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003257 else if ((!strcmp(argv[i], "-compress")) ||
3258 (!strcmp(argv[i], "--compress"))) {
3259 compress++;
3260 xmlSetCompressMode(9);
3261 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003262#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003263#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003264 else if ((!strcmp(argv[i], "-nowarning")) ||
3265 (!strcmp(argv[i], "--nowarning"))) {
3266 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003267 xmlPedanticParserDefault(0);
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003268 options |= XML_PARSE_NOWARNING;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003269 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003270 else if ((!strcmp(argv[i], "-pedantic")) ||
3271 (!strcmp(argv[i], "--pedantic"))) {
3272 xmlGetWarningsDefaultValue = 1;
3273 xmlPedanticParserDefault(1);
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003274 options |= XML_PARSE_PEDANTIC;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003275 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00003276#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003277 else if ((!strcmp(argv[i], "-debugent")) ||
3278 (!strcmp(argv[i], "--debugent"))) {
3279 debugent++;
3280 xmlParserDebugEntities = 1;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003281 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00003282#endif
Daniel Veillard25048d82004-08-14 22:37:54 +00003283#ifdef LIBXML_C14N_ENABLED
3284 else if ((!strcmp(argv[i], "-c14n")) ||
3285 (!strcmp(argv[i], "--c14n"))) {
3286 canonical++;
3287 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003288 }
Aleksey Sanin83868242009-07-09 10:26:22 +02003289 else if ((!strcmp(argv[i], "-c14n11")) ||
3290 (!strcmp(argv[i], "--c14n11"))) {
3291 canonical_11++;
3292 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003293 }
Aleksey Sanin2650df12005-06-06 17:16:50 +00003294 else if ((!strcmp(argv[i], "-exc-c14n")) ||
3295 (!strcmp(argv[i], "--exc-c14n"))) {
3296 exc_canonical++;
3297 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003298 }
Daniel Veillard25048d82004-08-14 22:37:54 +00003299#endif
Daniel Veillard81418e32001-05-22 15:08:55 +00003300#ifdef LIBXML_CATALOG_ENABLED
3301 else if ((!strcmp(argv[i], "-catalogs")) ||
3302 (!strcmp(argv[i], "--catalogs"))) {
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003303 catalogs++;
3304 } else if ((!strcmp(argv[i], "-nocatalogs")) ||
3305 (!strcmp(argv[i], "--nocatalogs"))) {
3306 nocatalogs++;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003307 }
Daniel Veillard81418e32001-05-22 15:08:55 +00003308#endif
Daniel Veillardbe803962000-06-28 23:40:59 +00003309 else if ((!strcmp(argv[i], "-encode")) ||
3310 (!strcmp(argv[i], "--encode"))) {
3311 i++;
3312 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003313 /*
3314 * OK it's for testing purposes
3315 */
3316 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +00003317 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003318 else if ((!strcmp(argv[i], "-noblanks")) ||
3319 (!strcmp(argv[i], "--noblanks"))) {
3320 noblanks++;
3321 xmlKeepBlanksDefault(0);
Daniel Veillard90493a92001-08-14 14:12:47 +00003322 }
Daniel Veillard87076042004-05-03 22:54:49 +00003323 else if ((!strcmp(argv[i], "-maxmem")) ||
3324 (!strcmp(argv[i], "--maxmem"))) {
3325 i++;
3326 if (sscanf(argv[i], "%d", &maxmem) == 1) {
3327 xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc,
3328 myStrdupFunc);
3329 } else {
3330 maxmem = 0;
3331 }
3332 }
Daniel Veillard90493a92001-08-14 14:12:47 +00003333 else if ((!strcmp(argv[i], "-format")) ||
3334 (!strcmp(argv[i], "--format"))) {
3335 noblanks++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003336#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard90493a92001-08-14 14:12:47 +00003337 format++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003338#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard90493a92001-08-14 14:12:47 +00003339 xmlKeepBlanksDefault(0);
Daniel Veillard7704fb12003-01-03 16:19:51 +00003340 }
Daniel Veillard81273902003-09-30 00:43:48 +00003341#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003342 else if ((!strcmp(argv[i], "-stream")) ||
3343 (!strcmp(argv[i], "--stream"))) {
3344 stream++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003345 }
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003346 else if ((!strcmp(argv[i], "-walker")) ||
3347 (!strcmp(argv[i], "--walker"))) {
3348 walker++;
3349 noout++;
3350 }
Daniel Veillard81273902003-09-30 00:43:48 +00003351#endif /* LIBXML_READER_ENABLED */
3352#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +00003353 else if ((!strcmp(argv[i], "-sax1")) ||
3354 (!strcmp(argv[i], "--sax1"))) {
Daniel Veillard023d0ba2009-07-29 11:34:50 +02003355 sax1++;
3356 options |= XML_PARSE_SAX1;
Daniel Veillard07cb8222003-09-10 10:51:05 +00003357 }
Daniel Veillard81273902003-09-30 00:43:48 +00003358#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003359 else if ((!strcmp(argv[i], "-sax")) ||
3360 (!strcmp(argv[i], "--sax"))) {
Daniel Veillard023d0ba2009-07-29 11:34:50 +02003361 sax++;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003362 }
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003363 else if ((!strcmp(argv[i], "-chkregister")) ||
3364 (!strcmp(argv[i], "--chkregister"))) {
Daniel Veillard023d0ba2009-07-29 11:34:50 +02003365 chkregister++;
Daniel Veillard71531f32003-02-05 13:19:53 +00003366#ifdef LIBXML_SCHEMAS_ENABLED
3367 } else if ((!strcmp(argv[i], "-relaxng")) ||
3368 (!strcmp(argv[i], "--relaxng"))) {
3369 i++;
3370 relaxng = argv[i];
3371 noent++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003372 options |= XML_PARSE_NOENT;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003373 } else if ((!strcmp(argv[i], "-schema")) ||
3374 (!strcmp(argv[i], "--schema"))) {
3375 i++;
3376 schema = argv[i];
3377 noent++;
Daniel Veillard71531f32003-02-05 13:19:53 +00003378#endif
Daniel Veillardd4501d72005-07-24 14:27:16 +00003379#ifdef LIBXML_SCHEMATRON_ENABLED
3380 } else if ((!strcmp(argv[i], "-schematron")) ||
3381 (!strcmp(argv[i], "--schematron"))) {
3382 i++;
3383 schematron = argv[i];
3384 noent++;
3385#endif
Daniel Veillarde8b09e42003-05-13 22:14:13 +00003386 } else if ((!strcmp(argv[i], "-nonet")) ||
3387 (!strcmp(argv[i], "--nonet"))) {
Daniel Veillard61b93382003-11-03 14:28:31 +00003388 options |= XML_PARSE_NONET;
Daniel Veillard968d6432006-04-25 16:17:53 +00003389 xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
Daniel Veillard8874b942005-08-25 13:19:21 +00003390 } else if ((!strcmp(argv[i], "-nocompact")) ||
3391 (!strcmp(argv[i], "--nocompact"))) {
3392 options &= ~XML_PARSE_COMPACT;
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003393 } else if ((!strcmp(argv[i], "-load-trace")) ||
3394 (!strcmp(argv[i], "--load-trace"))) {
3395 load_trace++;
3396 } else if ((!strcmp(argv[i], "-path")) ||
3397 (!strcmp(argv[i], "--path"))) {
3398 i++;
3399 parsePath(BAD_CAST argv[i]);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003400#ifdef LIBXML_PATTERN_ENABLED
3401 } else if ((!strcmp(argv[i], "-pattern")) ||
3402 (!strcmp(argv[i], "--pattern"))) {
3403 i++;
3404 pattern = argv[i];
3405#endif
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003406#ifdef LIBXML_XPATH_ENABLED
3407 } else if ((!strcmp(argv[i], "-xpath")) ||
3408 (!strcmp(argv[i], "--xpath"))) {
3409 i++;
3410 noout++;
3411 xpathquery = argv[i];
3412#endif
Daniel Veillard7e5c3f42008-07-29 16:12:31 +00003413 } else if ((!strcmp(argv[i], "-oldxml10")) ||
3414 (!strcmp(argv[i], "--oldxml10"))) {
3415 oldxml10++;
3416 options |= XML_PARSE_OLD10;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003417 } else {
3418 fprintf(stderr, "Unknown option %s\n", argv[i]);
3419 usage(argv[0]);
3420 return(1);
3421 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003422 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003423
3424#ifdef LIBXML_CATALOG_ENABLED
3425 if (nocatalogs == 0) {
3426 if (catalogs) {
3427 const char *catal;
3428
3429 catal = getenv("SGML_CATALOG_FILES");
Daniel Veillard6c5f9d12001-08-25 13:33:14 +00003430 if (catal != NULL) {
3431 xmlLoadCatalogs(catal);
3432 } else {
3433 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
3434 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003435 }
3436 }
3437#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003438
Daniel Veillard81273902003-09-30 00:43:48 +00003439#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +00003440 if (sax1)
3441 xmlSAXDefaultVersion(1);
3442 else
3443 xmlSAXDefaultVersion(2);
Daniel Veillard81273902003-09-30 00:43:48 +00003444#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillard07cb8222003-09-10 10:51:05 +00003445
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003446 if (chkregister) {
3447 xmlRegisterNodeDefault(registerNode);
3448 xmlDeregisterNodeDefault(deregisterNode);
3449 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02003450
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00003451 indent = getenv("XMLLINT_INDENT");
3452 if(indent != NULL) {
3453 xmlTreeIndentString = indent;
3454 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02003455
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003456
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003457 defaultEntityLoader = xmlGetExternalEntityLoader();
3458 xmlSetExternalEntityLoader(xmllintExternalEntityLoader);
3459
Daniel Veillardd9bad132001-07-23 19:39:43 +00003460 xmlLineNumbersDefault(1);
Daniel Veillard48da9102001-08-07 01:10:10 +00003461 if (loaddtd != 0)
3462 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
3463 if (dtdattrs)
3464 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003465 if (noent != 0) xmlSubstituteEntitiesDefault(1);
Daniel Veillard4432df22003-09-28 18:58:27 +00003466#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003467 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
Daniel Veillard4432df22003-09-28 18:58:27 +00003468#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003469 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003470 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003471 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003472 xmlGenericError(xmlGenericErrorContext,
3473 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
3474 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003475 "<html><head><title>%s output</title></head>\n",
3476 argv[0]);
Daniel Veillardf1edb102009-08-10 14:43:18 +02003477 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003478 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
3479 argv[0]);
3480 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003481
Daniel Veillardd4501d72005-07-24 14:27:16 +00003482#ifdef LIBXML_SCHEMATRON_ENABLED
3483 if ((schematron != NULL) && (sax == 0)
3484#ifdef LIBXML_READER_ENABLED
3485 && (stream == 0)
3486#endif /* LIBXML_READER_ENABLED */
3487 ) {
3488 xmlSchematronParserCtxtPtr ctxt;
3489
3490 /* forces loading the DTDs */
Daniel Veillardf1edb102009-08-10 14:43:18 +02003491 xmlLoadExtDtdDefaultValue |= 1;
Daniel Veillardd4501d72005-07-24 14:27:16 +00003492 options |= XML_PARSE_DTDLOAD;
3493 if (timing) {
3494 startTimer();
3495 }
3496 ctxt = xmlSchematronNewParserCtxt(schematron);
3497#if 0
3498 xmlSchematronSetParserErrors(ctxt,
3499 (xmlSchematronValidityErrorFunc) fprintf,
3500 (xmlSchematronValidityWarningFunc) fprintf,
3501 stderr);
3502#endif
3503 wxschematron = xmlSchematronParse(ctxt);
3504 if (wxschematron == NULL) {
3505 xmlGenericError(xmlGenericErrorContext,
3506 "Schematron schema %s failed to compile\n", schematron);
3507 progresult = XMLLINT_ERR_SCHEMACOMP;
3508 schematron = NULL;
3509 }
3510 xmlSchematronFreeParserCtxt(ctxt);
3511 if (timing) {
3512 endTimer("Compiling the schemas");
3513 }
3514 }
3515#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00003516#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003517 if ((relaxng != NULL) && (sax == 0)
Daniel Veillard81273902003-09-30 00:43:48 +00003518#ifdef LIBXML_READER_ENABLED
3519 && (stream == 0)
3520#endif /* LIBXML_READER_ENABLED */
3521 ) {
Daniel Veillard71531f32003-02-05 13:19:53 +00003522 xmlRelaxNGParserCtxtPtr ctxt;
3523
Daniel Veillardce192eb2003-04-16 15:58:05 +00003524 /* forces loading the DTDs */
Daniel Veillardf1edb102009-08-10 14:43:18 +02003525 xmlLoadExtDtdDefaultValue |= 1;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003526 options |= XML_PARSE_DTDLOAD;
Daniel Veillard42f12e92003-03-07 18:32:59 +00003527 if (timing) {
3528 startTimer();
3529 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003530 ctxt = xmlRelaxNGNewParserCtxt(relaxng);
3531 xmlRelaxNGSetParserErrors(ctxt,
3532 (xmlRelaxNGValidityErrorFunc) fprintf,
3533 (xmlRelaxNGValidityWarningFunc) fprintf,
3534 stderr);
3535 relaxngschemas = xmlRelaxNGParse(ctxt);
Daniel Veillardce192eb2003-04-16 15:58:05 +00003536 if (relaxngschemas == NULL) {
3537 xmlGenericError(xmlGenericErrorContext,
3538 "Relax-NG schema %s failed to compile\n", relaxng);
William M. Brack8304d872004-06-08 13:29:32 +00003539 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillardce192eb2003-04-16 15:58:05 +00003540 relaxng = NULL;
3541 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003542 xmlRelaxNGFreeParserCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00003543 if (timing) {
3544 endTimer("Compiling the schemas");
3545 }
Daniel Veillardebe25d42004-03-25 09:35:49 +00003546 } else if ((schema != NULL)
3547#ifdef LIBXML_READER_ENABLED
Daniel Veillardf10ae122005-07-10 19:03:16 +00003548 && (stream == 0)
Daniel Veillardebe25d42004-03-25 09:35:49 +00003549#endif
3550 ) {
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003551 xmlSchemaParserCtxtPtr ctxt;
3552
3553 if (timing) {
3554 startTimer();
3555 }
3556 ctxt = xmlSchemaNewParserCtxt(schema);
3557 xmlSchemaSetParserErrors(ctxt,
3558 (xmlSchemaValidityErrorFunc) fprintf,
3559 (xmlSchemaValidityWarningFunc) fprintf,
3560 stderr);
3561 wxschemas = xmlSchemaParse(ctxt);
3562 if (wxschemas == NULL) {
3563 xmlGenericError(xmlGenericErrorContext,
3564 "WXS schema %s failed to compile\n", schema);
William M. Brack8304d872004-06-08 13:29:32 +00003565 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003566 schema = NULL;
3567 }
3568 xmlSchemaFreeParserCtxt(ctxt);
3569 if (timing) {
3570 endTimer("Compiling the schemas");
3571 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003572 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003573#endif /* LIBXML_SCHEMAS_ENABLED */
3574#ifdef LIBXML_PATTERN_ENABLED
Daniel Veillard39e5c892005-07-03 22:48:50 +00003575 if ((pattern != NULL)
Daniel Veillardc9352532005-07-04 14:25:34 +00003576#ifdef LIBXML_READER_ENABLED
Daniel Veillard39e5c892005-07-03 22:48:50 +00003577 && (walker == 0)
3578#endif
3579 ) {
Daniel Veillardffa7b7e2003-12-05 16:10:21 +00003580 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003581 if (patternc == NULL) {
3582 xmlGenericError(xmlGenericErrorContext,
3583 "Pattern %s failed to compile\n", pattern);
William M. Brack8304d872004-06-08 13:29:32 +00003584 progresult = XMLLINT_ERR_SCHEMAPAT;
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003585 pattern = NULL;
3586 }
3587 }
3588#endif /* LIBXML_PATTERN_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003589 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +00003590 if ((!strcmp(argv[i], "-encode")) ||
3591 (!strcmp(argv[i], "--encode"))) {
3592 i++;
3593 continue;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003594 } else if ((!strcmp(argv[i], "-o")) ||
3595 (!strcmp(argv[i], "-output")) ||
3596 (!strcmp(argv[i], "--output"))) {
3597 i++;
3598 continue;
Daniel Veillardbe803962000-06-28 23:40:59 +00003599 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003600#ifdef LIBXML_VALID_ENABLED
Daniel Veillardcd429612000-10-11 15:57:05 +00003601 if ((!strcmp(argv[i], "-dtdvalid")) ||
3602 (!strcmp(argv[i], "--dtdvalid"))) {
3603 i++;
3604 continue;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003605 }
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003606 if ((!strcmp(argv[i], "-path")) ||
3607 (!strcmp(argv[i], "--path"))) {
3608 i++;
3609 continue;
Daniel Veillardcd429612000-10-11 15:57:05 +00003610 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00003611 if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3612 (!strcmp(argv[i], "--dtdvalidfpi"))) {
3613 i++;
3614 continue;
3615 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003616#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard71531f32003-02-05 13:19:53 +00003617 if ((!strcmp(argv[i], "-relaxng")) ||
3618 (!strcmp(argv[i], "--relaxng"))) {
3619 i++;
3620 continue;
3621 }
Daniel Veillard87076042004-05-03 22:54:49 +00003622 if ((!strcmp(argv[i], "-maxmem")) ||
3623 (!strcmp(argv[i], "--maxmem"))) {
3624 i++;
3625 continue;
3626 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003627 if ((!strcmp(argv[i], "-schema")) ||
3628 (!strcmp(argv[i], "--schema"))) {
3629 i++;
3630 continue;
3631 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00003632 if ((!strcmp(argv[i], "-schematron")) ||
3633 (!strcmp(argv[i], "--schematron"))) {
3634 i++;
3635 continue;
3636 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003637#ifdef LIBXML_PATTERN_ENABLED
3638 if ((!strcmp(argv[i], "-pattern")) ||
3639 (!strcmp(argv[i], "--pattern"))) {
3640 i++;
3641 continue;
3642 }
3643#endif
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003644#ifdef LIBXML_XPATH_ENABLED
3645 if ((!strcmp(argv[i], "-xpath")) ||
3646 (!strcmp(argv[i], "--xpath"))) {
3647 i++;
3648 continue;
3649 }
3650#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00003651 if ((timing) && (repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00003652 startTimer();
Daniel Veillardcbaf3992001-12-31 16:16:02 +00003653 /* Remember file names. "-" means stdin. <sven@zen.org> */
Daniel Veillard4a6845d2001-01-03 13:32:39 +00003654 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003655 if (repeat) {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003656 xmlParserCtxtPtr ctxt = NULL;
3657
3658 for (acount = 0;acount < repeat;acount++) {
Daniel Veillard81273902003-09-30 00:43:48 +00003659#ifdef LIBXML_READER_ENABLED
Daniel Veillard198c1bf2003-10-20 17:07:41 +00003660 if (stream != 0) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00003661 streamFile(argv[i]);
Daniel Veillard198c1bf2003-10-20 17:07:41 +00003662 } else {
Daniel Veillard81273902003-09-30 00:43:48 +00003663#endif /* LIBXML_READER_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003664 if (sax) {
3665 testSAX(argv[i]);
3666 } else {
3667 if (ctxt == NULL)
3668 ctxt = xmlNewParserCtxt();
3669 parseAndPrintFile(argv[i], ctxt);
3670 }
Daniel Veillard81273902003-09-30 00:43:48 +00003671#ifdef LIBXML_READER_ENABLED
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003672 }
Daniel Veillard81273902003-09-30 00:43:48 +00003673#endif /* LIBXML_READER_ENABLED */
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003674 }
3675 if (ctxt != NULL)
3676 xmlFreeParserCtxt(ctxt);
Daniel Veillard7704fb12003-01-03 16:19:51 +00003677 } else {
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003678 nbregister = 0;
3679
Daniel Veillard81273902003-09-30 00:43:48 +00003680#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003681 if (stream != 0)
3682 streamFile(argv[i]);
3683 else
Daniel Veillard81273902003-09-30 00:43:48 +00003684#endif /* LIBXML_READER_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003685 if (sax) {
3686 testSAX(argv[i]);
3687 } else {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003688 parseAndPrintFile(argv[i], NULL);
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003689 }
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003690
3691 if ((chkregister) && (nbregister != 0)) {
3692 fprintf(stderr, "Registration count off: %d\n", nbregister);
William M. Brack8304d872004-06-08 13:29:32 +00003693 progresult = XMLLINT_ERR_RDREGIS;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003694 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00003695 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003696 files ++;
Daniel Veillarda7866932001-12-04 13:14:44 +00003697 if ((timing) && (repeat)) {
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00003698 endTimer("%d iterations", repeat);
Daniel Veillarda7866932001-12-04 13:14:44 +00003699 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00003700 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003701 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02003702 if (generate)
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003703 parseAndPrintFile(NULL, NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003704 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003705 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003706 }
Daniel Veillard845cce42002-01-09 11:51:37 +00003707 if ((files == 0) && (!generate) && (version == 0)) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003708 usage(argv[0]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003709 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00003710#ifdef LIBXML_SCHEMATRON_ENABLED
3711 if (wxschematron != NULL)
3712 xmlSchematronFree(wxschematron);
3713#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00003714#ifdef LIBXML_SCHEMAS_ENABLED
3715 if (relaxngschemas != NULL)
3716 xmlRelaxNGFree(relaxngschemas);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003717 if (wxschemas != NULL)
3718 xmlSchemaFree(wxschemas);
Daniel Veillard71531f32003-02-05 13:19:53 +00003719 xmlRelaxNGCleanupTypes();
3720#endif
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003721#ifdef LIBXML_PATTERN_ENABLED
3722 if (patternc != NULL)
3723 xmlFreePattern(patternc);
3724#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003725 xmlCleanupParser();
3726 xmlMemoryDump();
3727
Daniel Veillardf7cd4812001-02-23 18:44:52 +00003728 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003729}
Daniel Veillard88a172f2000-08-04 18:23:10 +00003730