blob: b7af32f090fe5ddc909d83959c2a7cb270dd648d [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) {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002513 if (format == 1) {
Daniel Veillard42fd4122003-11-04 08:47:48 +00002514 htmlSaveFileFormat(output ? output : "-", doc, encoding, 1);
2515 }
2516 else {
2517 htmlSaveFileFormat(output ? output : "-", doc, encoding, 0);
2518 }
2519 }
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002520 else if (format == 1) {
Daniel Veillard42fd4122003-11-04 08:47:48 +00002521 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) {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002592 if (format == 1) {
Daniel Veillardd536f702001-11-08 17:32:47 +00002593 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 {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002598 if (format == 1)
Daniel Veillard90493a92001-08-14 14:12:47 +00002599 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) {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002617 if (format == 1) {
Daniel Veillarddab39b52006-10-16 23:22:10 +00002618 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 }
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002630 } else if (format == 1) {
Daniel Veillarddab39b52006-10-16 23:22:10 +00002631 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
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002659 if (format == 1)
Daniel Veillarddab39b52006-10-16 23:22:10 +00002660 saveOpts |= XML_SAVE_FORMAT;
Adam Spraggd2e62312010-11-03 15:33:40 +01002661 else if (format == 2)
2662 saveOpts |= XML_SAVE_WSNONSIG;
Daniel Veillard9ccea572010-03-10 15:02:49 +01002663
2664#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
Daniel Veillard9d962642009-08-23 15:31:18 +02002665 if (xmlout)
2666 saveOpts |= XML_SAVE_AS_XML;
Daniel Veillard9ccea572010-03-10 15:02:49 +01002667#endif
Daniel Veillarddab39b52006-10-16 23:22:10 +00002668
2669 if (output == NULL)
2670 ctxt = xmlSaveToFd(1, encoding, saveOpts);
2671 else
2672 ctxt = xmlSaveToFilename(output, encoding, saveOpts);
2673
2674 if (ctxt != NULL) {
2675 if (xmlSaveDoc(ctxt, doc) < 0) {
2676 fprintf(stderr, "failed save to %s\n",
2677 output ? output : "-");
2678 progresult = XMLLINT_ERR_OUT;
2679 }
2680 xmlSaveClose(ctxt);
2681 } else {
William M. Brack8304d872004-06-08 13:29:32 +00002682 progresult = XMLLINT_ERR_OUT;
Daniel Veillard05d987b2003-10-08 11:54:57 +00002683 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002684 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002685 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002686 endTimer("Saving");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002687 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002688#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002689 } else {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002690 FILE *out;
2691 if (output == NULL)
2692 out = stdout;
2693 else {
2694 out = fopen(output,"wb");
2695 }
Daniel Veillard05d987b2003-10-08 11:54:57 +00002696 if (out != NULL) {
2697 xmlDebugDumpDocument(out, doc);
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002698
Daniel Veillard05d987b2003-10-08 11:54:57 +00002699 if (output != NULL)
2700 fclose(out);
2701 } else {
2702 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00002703 progresult = XMLLINT_ERR_OUT;
Daniel Veillard05d987b2003-10-08 11:54:57 +00002704 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002705 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002706#endif
2707 }
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002708#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002709
Daniel Veillard4432df22003-09-28 18:58:27 +00002710#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002711 /*
2712 * A posteriori validation test
2713 */
Daniel Veillard66f68e72003-08-18 16:39:51 +00002714 if ((dtdvalid != NULL) || (dtdvalidfpi != NULL)) {
Daniel Veillardcd429612000-10-11 15:57:05 +00002715 xmlDtdPtr dtd;
2716
Daniel Veillard48b2f892001-02-25 16:11:03 +00002717 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002718 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002719 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00002720 if (dtdvalid != NULL)
Daniel Veillardf1edb102009-08-10 14:43:18 +02002721 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
Daniel Veillard66f68e72003-08-18 16:39:51 +00002722 else
Daniel Veillardf1edb102009-08-10 14:43:18 +02002723 dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL);
Daniel Veillard48b2f892001-02-25 16:11:03 +00002724 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002725 endTimer("Parsing DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002726 }
Daniel Veillardcd429612000-10-11 15:57:05 +00002727 if (dtd == NULL) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00002728 if (dtdvalid != NULL)
2729 xmlGenericError(xmlGenericErrorContext,
2730 "Could not parse DTD %s\n", dtdvalid);
2731 else
2732 xmlGenericError(xmlGenericErrorContext,
2733 "Could not parse DTD %s\n", dtdvalidfpi);
William M. Brack8304d872004-06-08 13:29:32 +00002734 progresult = XMLLINT_ERR_DTD;
Daniel Veillardcd429612000-10-11 15:57:05 +00002735 } else {
Daniel Veillarda37aab82003-06-09 09:10:36 +00002736 xmlValidCtxtPtr cvp;
2737
2738 if ((cvp = xmlNewValidCtxt()) == NULL) {
2739 xmlGenericError(xmlGenericErrorContext,
2740 "Couldn't allocate validation context\n");
2741 exit(-1);
2742 }
2743 cvp->userData = (void *) stderr;
2744 cvp->error = (xmlValidityErrorFunc) fprintf;
2745 cvp->warning = (xmlValidityWarningFunc) fprintf;
2746
Daniel Veillard48b2f892001-02-25 16:11:03 +00002747 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002748 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002749 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002750 if (!xmlValidateDtd(cvp, doc, dtd)) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00002751 if (dtdvalid != NULL)
2752 xmlGenericError(xmlGenericErrorContext,
2753 "Document %s does not validate against %s\n",
2754 filename, dtdvalid);
2755 else
2756 xmlGenericError(xmlGenericErrorContext,
2757 "Document %s does not validate against %s\n",
2758 filename, dtdvalidfpi);
William M. Brack8304d872004-06-08 13:29:32 +00002759 progresult = XMLLINT_ERR_VALID;
Daniel Veillardcd429612000-10-11 15:57:05 +00002760 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002761 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002762 endTimer("Validating against DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002763 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002764 xmlFreeValidCtxt(cvp);
Daniel Veillardcd429612000-10-11 15:57:05 +00002765 xmlFreeDtd(dtd);
2766 }
2767 } else if (postvalid) {
Daniel Veillarda37aab82003-06-09 09:10:36 +00002768 xmlValidCtxtPtr cvp;
2769
2770 if ((cvp = xmlNewValidCtxt()) == NULL) {
2771 xmlGenericError(xmlGenericErrorContext,
2772 "Couldn't allocate validation context\n");
2773 exit(-1);
2774 }
2775
Daniel Veillard48b2f892001-02-25 16:11:03 +00002776 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002777 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002778 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002779 cvp->userData = (void *) stderr;
2780 cvp->error = (xmlValidityErrorFunc) fprintf;
2781 cvp->warning = (xmlValidityWarningFunc) fprintf;
2782 if (!xmlValidateDocument(cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00002783 xmlGenericError(xmlGenericErrorContext,
2784 "Document %s does not validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002785 progresult = XMLLINT_ERR_VALID;
Daniel Veillardcd429612000-10-11 15:57:05 +00002786 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002787 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002788 endTimer("Validating");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002789 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002790 xmlFreeValidCtxt(cvp);
Daniel Veillard4432df22003-09-28 18:58:27 +00002791 }
2792#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardd4501d72005-07-24 14:27:16 +00002793#ifdef LIBXML_SCHEMATRON_ENABLED
2794 if (wxschematron != NULL) {
2795 xmlSchematronValidCtxtPtr ctxt;
2796 int ret;
Daniel Veillardc740a172005-07-31 12:17:24 +00002797 int flag;
Daniel Veillardd4501d72005-07-24 14:27:16 +00002798
2799 if ((timing) && (!repeat)) {
2800 startTimer();
2801 }
2802
2803 if (debug)
2804 flag = XML_SCHEMATRON_OUT_XML;
Daniel Veillardc740a172005-07-31 12:17:24 +00002805 else
2806 flag = XML_SCHEMATRON_OUT_TEXT;
2807 if (noout)
2808 flag |= XML_SCHEMATRON_OUT_QUIET;
Daniel Veillardd4501d72005-07-24 14:27:16 +00002809 ctxt = xmlSchematronNewValidCtxt(wxschematron, flag);
2810#if 0
2811 xmlSchematronSetValidErrors(ctxt,
2812 (xmlSchematronValidityErrorFunc) fprintf,
2813 (xmlSchematronValidityWarningFunc) fprintf,
2814 stderr);
2815#endif
2816 ret = xmlSchematronValidateDoc(ctxt, doc);
2817 if (ret == 0) {
2818 fprintf(stderr, "%s validates\n", filename);
2819 } else if (ret > 0) {
2820 fprintf(stderr, "%s fails to validate\n", filename);
2821 progresult = XMLLINT_ERR_VALID;
2822 } else {
2823 fprintf(stderr, "%s validation generated an internal error\n",
2824 filename);
2825 progresult = XMLLINT_ERR_VALID;
2826 }
2827 xmlSchematronFreeValidCtxt(ctxt);
2828 if ((timing) && (!repeat)) {
2829 endTimer("Validating");
2830 }
2831 }
2832#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00002833#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard4432df22003-09-28 18:58:27 +00002834 if (relaxngschemas != NULL) {
Daniel Veillard71531f32003-02-05 13:19:53 +00002835 xmlRelaxNGValidCtxtPtr ctxt;
2836 int ret;
2837
Daniel Veillard42f12e92003-03-07 18:32:59 +00002838 if ((timing) && (!repeat)) {
2839 startTimer();
2840 }
2841
Daniel Veillard71531f32003-02-05 13:19:53 +00002842 ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
2843 xmlRelaxNGSetValidErrors(ctxt,
2844 (xmlRelaxNGValidityErrorFunc) fprintf,
2845 (xmlRelaxNGValidityWarningFunc) fprintf,
2846 stderr);
2847 ret = xmlRelaxNGValidateDoc(ctxt, doc);
2848 if (ret == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002849 fprintf(stderr, "%s validates\n", filename);
Daniel Veillard71531f32003-02-05 13:19:53 +00002850 } else if (ret > 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002851 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002852 progresult = XMLLINT_ERR_VALID;
Daniel Veillard71531f32003-02-05 13:19:53 +00002853 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002854 fprintf(stderr, "%s validation generated an internal error\n",
Daniel Veillard71531f32003-02-05 13:19:53 +00002855 filename);
William M. Brack8304d872004-06-08 13:29:32 +00002856 progresult = XMLLINT_ERR_VALID;
Daniel Veillard71531f32003-02-05 13:19:53 +00002857 }
2858 xmlRelaxNGFreeValidCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00002859 if ((timing) && (!repeat)) {
2860 endTimer("Validating");
2861 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002862 } else if (wxschemas != NULL) {
2863 xmlSchemaValidCtxtPtr ctxt;
2864 int ret;
2865
2866 if ((timing) && (!repeat)) {
2867 startTimer();
2868 }
2869
2870 ctxt = xmlSchemaNewValidCtxt(wxschemas);
2871 xmlSchemaSetValidErrors(ctxt,
2872 (xmlSchemaValidityErrorFunc) fprintf,
2873 (xmlSchemaValidityWarningFunc) fprintf,
2874 stderr);
2875 ret = xmlSchemaValidateDoc(ctxt, doc);
2876 if (ret == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002877 fprintf(stderr, "%s validates\n", filename);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002878 } else if (ret > 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002879 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002880 progresult = XMLLINT_ERR_VALID;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002881 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002882 fprintf(stderr, "%s validation generated an internal error\n",
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002883 filename);
William M. Brack8304d872004-06-08 13:29:32 +00002884 progresult = XMLLINT_ERR_VALID;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002885 }
2886 xmlSchemaFreeValidCtxt(ctxt);
2887 if ((timing) && (!repeat)) {
2888 endTimer("Validating");
2889 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002890 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002891#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002892
2893#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillard6b099012008-11-06 13:47:39 +00002894#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002895 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00002896 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002897#endif
Daniel Veillard6b099012008-11-06 13:47:39 +00002898#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002899
2900 /*
2901 * free it.
2902 */
Daniel Veillard48b2f892001-02-25 16:11:03 +00002903 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002904 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002905 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002906 xmlFreeDoc(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +00002907 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002908 endTimer("Freeing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002909 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002910}
2911
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002912/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +02002913 * *
2914 * Usage and Main *
2915 * *
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002916 ************************************************************************/
2917
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002918static void showVersion(const char *name) {
2919 fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
2920 fprintf(stderr, " compiled with: ");
Daniel Veillard602434d2005-09-12 09:20:31 +00002921 if (xmlHasFeature(XML_WITH_THREAD)) fprintf(stderr, "Threads ");
2922 if (xmlHasFeature(XML_WITH_TREE)) fprintf(stderr, "Tree ");
2923 if (xmlHasFeature(XML_WITH_OUTPUT)) fprintf(stderr, "Output ");
2924 if (xmlHasFeature(XML_WITH_PUSH)) fprintf(stderr, "Push ");
2925 if (xmlHasFeature(XML_WITH_READER)) fprintf(stderr, "Reader ");
2926 if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(stderr, "Patterns ");
2927 if (xmlHasFeature(XML_WITH_WRITER)) fprintf(stderr, "Writer ");
2928 if (xmlHasFeature(XML_WITH_SAX1)) fprintf(stderr, "SAXv1 ");
Daniel Veillardf1edb102009-08-10 14:43:18 +02002929 if (xmlHasFeature(XML_WITH_FTP)) fprintf(stderr, "FTP ");
2930 if (xmlHasFeature(XML_WITH_HTTP)) fprintf(stderr, "HTTP ");
Daniel Veillard602434d2005-09-12 09:20:31 +00002931 if (xmlHasFeature(XML_WITH_VALID)) fprintf(stderr, "DTDValid ");
Daniel Veillardf1edb102009-08-10 14:43:18 +02002932 if (xmlHasFeature(XML_WITH_HTML)) fprintf(stderr, "HTML ");
2933 if (xmlHasFeature(XML_WITH_LEGACY)) fprintf(stderr, "Legacy ");
2934 if (xmlHasFeature(XML_WITH_C14N)) fprintf(stderr, "C14N ");
2935 if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(stderr, "Catalog ");
2936 if (xmlHasFeature(XML_WITH_XPATH)) fprintf(stderr, "XPath ");
2937 if (xmlHasFeature(XML_WITH_XPTR)) fprintf(stderr, "XPointer ");
2938 if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(stderr, "XInclude ");
2939 if (xmlHasFeature(XML_WITH_ICONV)) fprintf(stderr, "Iconv ");
2940 if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(stderr, "ISO8859X ");
2941 if (xmlHasFeature(XML_WITH_UNICODE)) fprintf(stderr, "Unicode ");
2942 if (xmlHasFeature(XML_WITH_REGEXP)) fprintf(stderr, "Regexps ");
2943 if (xmlHasFeature(XML_WITH_AUTOMATA)) fprintf(stderr, "Automata ");
2944 if (xmlHasFeature(XML_WITH_EXPR)) fprintf(stderr, "Expr ");
2945 if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(stderr, "Schemas ");
2946 if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(stderr, "Schematron ");
2947 if (xmlHasFeature(XML_WITH_MODULES)) fprintf(stderr, "Modules ");
2948 if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(stderr, "Debug ");
2949 if (xmlHasFeature(XML_WITH_DEBUG_MEM)) fprintf(stderr, "MemDebug ");
2950 if (xmlHasFeature(XML_WITH_DEBUG_RUN)) fprintf(stderr, "RunDebug ");
Daniel Veillard75acfee2006-07-13 06:29:56 +00002951 if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(stderr, "Zlib ");
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002952 fprintf(stderr, "\n");
2953}
2954
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002955static void usage(const char *name) {
2956 printf("Usage : %s [options] XMLfiles ...\n", name);
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002957#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002958 printf("\tParse the XML files and output the result of the parsing\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002959#else
2960 printf("\tParse the XML files\n");
2961#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002962 printf("\t--version : display the version of the XML library used\n");
2963#ifdef LIBXML_DEBUG_ENABLED
2964 printf("\t--debug : dump a debug tree of the in-memory document\n");
2965 printf("\t--shell : run a navigating shell\n");
2966 printf("\t--debugent : debug the entities defined in the document\n");
Daniel Veillard8326e732003-01-07 00:19:07 +00002967#else
Daniel Veillard81273902003-09-30 00:43:48 +00002968#ifdef LIBXML_READER_ENABLED
Daniel Veillard8326e732003-01-07 00:19:07 +00002969 printf("\t--debug : dump the nodes content when using --stream\n");
Daniel Veillard81273902003-09-30 00:43:48 +00002970#endif /* LIBXML_READER_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002971#endif
Daniel Veillard652327a2003-09-29 18:02:38 +00002972#ifdef LIBXML_TREE_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002973 printf("\t--copy : used to test the internal copy implementation\n");
Daniel Veillard652327a2003-09-29 18:02:38 +00002974#endif /* LIBXML_TREE_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002975 printf("\t--recover : output what was parsable on broken XML documents\n");
Daniel Veillard8915c152008-08-26 13:05:34 +00002976 printf("\t--huge : remove any internal arbitrary parser limits\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002977 printf("\t--noent : substitute entity references by their value\n");
2978 printf("\t--noout : don't output the result tree\n");
Daniel Veillard0bff36d2004-08-31 09:37:03 +00002979 printf("\t--path 'paths': provide a set of paths for resources\n");
2980 printf("\t--load-trace : print trace of all external entites loaded\n");
Daniel Veillarde8b09e42003-05-13 22:14:13 +00002981 printf("\t--nonet : refuse to fetch DTDs or entities over network\n");
Daniel Veillard8874b942005-08-25 13:19:21 +00002982 printf("\t--nocompact : do not generate compact text nodes\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002983 printf("\t--htmlout : output results as HTML\n");
Daniel Veillard05c13a22001-09-09 08:38:09 +00002984 printf("\t--nowrap : do not put HTML doc wrapper\n");
Daniel Veillard4432df22003-09-28 18:58:27 +00002985#ifdef LIBXML_VALID_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002986 printf("\t--valid : validate the document in addition to std well-formed check\n");
2987 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
2988 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
Daniel Veillard66f68e72003-08-18 16:39:51 +00002989 printf("\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
Daniel Veillard4432df22003-09-28 18:58:27 +00002990#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002991 printf("\t--timing : print some timings\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002992 printf("\t--output file or -o file: save to a given file\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002993 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
2994 printf("\t--insert : ad-hoc test for valid insertions\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002995#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002996#ifdef HAVE_ZLIB_H
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002997 printf("\t--compress : turn on gzip compression of output\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002998#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002999#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003000#ifdef LIBXML_HTML_ENABLED
3001 printf("\t--html : use the HTML parser\n");
Daniel Veillard42fd4122003-11-04 08:47:48 +00003002 printf("\t--xmlout : force to use the XML serializer when using --html\n");
Daniel Veillardf1121c42010-07-26 14:02:42 +02003003 printf("\t--nodefdtd : do not default HTML doctype\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003004#endif
Daniel Veillard73b013f2003-09-30 12:36:01 +00003005#ifdef LIBXML_PUSH_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003006 printf("\t--push : use the push mode of the parser\n");
Daniel Veillard73b013f2003-09-30 12:36:01 +00003007#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003008#ifdef HAVE_SYS_MMAN_H
3009 printf("\t--memory : parse from memory\n");
3010#endif
Daniel Veillard87076042004-05-03 22:54:49 +00003011 printf("\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003012 printf("\t--nowarning : do not emit warnings from parser/validator\n");
3013 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
Daniel Veillarddca8cc72003-09-26 13:53:14 +00003014 printf("\t--nocdata : replace cdata section with text nodes\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003015#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard90493a92001-08-14 14:12:47 +00003016 printf("\t--format : reformat/reindent the input\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003017 printf("\t--encode encoding : output in the given encoding\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003018 printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
Adam Spraggd2e62312010-11-03 15:33:40 +01003019 printf("\t--pretty STYLE : pretty-print in a particular style\n");
3020 printf("\t 0 Do not pretty print\n");
3021 printf("\t 1 Format the XML content, as --format\n");
3022 printf("\t 2 Add whitespace inside tags, preserving content\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003023#endif /* LIBXML_OUTPUT_ENABLED */
Aleksey Sanin83868242009-07-09 10:26:22 +02003024 printf("\t--c14n : save in W3C canonical format v1.0 (with comments)\n");
3025 printf("\t--c14n11 : save in W3C canonical format v1.1 (with comments)\n");
Aleksey Sanin2650df12005-06-06 17:16:50 +00003026 printf("\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n");
Daniel Veillard25048d82004-08-14 22:37:54 +00003027#ifdef LIBXML_C14N_ENABLED
3028#endif /* LIBXML_C14N_ENABLED */
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003029 printf("\t--nsclean : remove redundant namespace declarations\n");
3030 printf("\t--testIO : test user I/O support\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003031#ifdef LIBXML_CATALOG_ENABLED
Daniel Veillardbd9b0e82001-11-26 10:32:08 +00003032 printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
3033 printf("\t otherwise XML Catalogs starting from \n");
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003034 printf("\t %s are activated by default\n", XML_XML_DEFAULT_CATALOG);
Daniel Veillard05c13a22001-09-09 08:38:09 +00003035 printf("\t--nocatalogs: deactivate all catalogs\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003036#endif
3037 printf("\t--auto : generate a small doc on the fly\n");
3038#ifdef LIBXML_XINCLUDE_ENABLED
3039 printf("\t--xinclude : do XInclude processing\n");
Daniel Veillardc14c3892004-08-16 12:34:50 +00003040 printf("\t--noxincludenode : same but do not generate XInclude nodes\n");
Daniel Veillard54bd29b2008-08-26 07:26:55 +00003041 printf("\t--nofixup-base-uris : do not fixup xml:base uris\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003042#endif
Daniel Veillardcbaf3992001-12-31 16:16:02 +00003043 printf("\t--loaddtd : fetch external DTD\n");
Daniel Veillard48da9102001-08-07 01:10:10 +00003044 printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
Daniel Veillard81273902003-09-30 00:43:48 +00003045#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003046 printf("\t--stream : use the streaming interface to process very large files\n");
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003047 printf("\t--walker : create a reader and walk though the resulting doc\n");
Daniel Veillard81273902003-09-30 00:43:48 +00003048#endif /* LIBXML_READER_ENABLED */
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003049#ifdef LIBXML_PATTERN_ENABLED
3050 printf("\t--pattern pattern_value : test the pattern support\n");
3051#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003052 printf("\t--chkregister : verify the node registration code\n");
Daniel Veillardef4d3bc2003-02-07 12:38:22 +00003053#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard71531f32003-02-05 13:19:53 +00003054 printf("\t--relaxng schema : do RelaxNG validation against the schema\n");
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003055 printf("\t--schema schema : do validation against the WXS schema\n");
Daniel Veillard71531f32003-02-05 13:19:53 +00003056#endif
Daniel Veillarde70375c2005-07-30 21:09:12 +00003057#ifdef LIBXML_SCHEMATRON_ENABLED
3058 printf("\t--schematron schema : do validation against a schematron\n");
3059#endif
Daniel Veillard971771e2005-07-09 17:32:57 +00003060#ifdef LIBXML_SAX1_ENABLED
3061 printf("\t--sax1: use the old SAX1 interfaces for processing\n");
3062#endif
3063 printf("\t--sax: do not build a tree but work just at the SAX level\n");
Daniel Veillard7e5c3f42008-07-29 16:12:31 +00003064 printf("\t--oldxml10: use XML-1.0 parsing rules before the 5th edition\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003065#ifdef LIBXML_XPATH_ENABLED
3066 printf("\t--xpath expr: evaluate the XPath expression, inply --noout\n");
3067#endif
Daniel Veillard971771e2005-07-09 17:32:57 +00003068
Daniel Veillarda42f25f2002-01-25 14:15:40 +00003069 printf("\nLibxml project home page: http://xmlsoft.org/\n");
3070 printf("To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003071}
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003072
3073static void registerNode(xmlNodePtr node)
3074{
3075 node->_private = malloc(sizeof(long));
3076 *(long*)node->_private = (long) 0x81726354;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003077 nbregister++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003078}
3079
3080static void deregisterNode(xmlNodePtr node)
3081{
3082 assert(node->_private != NULL);
3083 assert(*(long*)node->_private == (long) 0x81726354);
3084 free(node->_private);
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003085 nbregister--;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003086}
3087
Daniel Veillard4a6845d2001-01-03 13:32:39 +00003088int
3089main(int argc, char **argv) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00003090 int i, acount;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003091 int files = 0;
Daniel Veillard845cce42002-01-09 11:51:37 +00003092 int version = 0;
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00003093 const char* indent;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003094
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003095 if (argc <= 1) {
3096 usage(argv[0]);
3097 return(1);
3098 }
Daniel Veillardbe803962000-06-28 23:40:59 +00003099 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003100 for (i = 1; i < argc ; i++) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003101 if (!strcmp(argv[i], "-"))
3102 break;
3103
3104 if (argv[i][0] != '-')
3105 continue;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003106 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
3107 debug++;
Daniel Veillard56ada1d2003-01-07 11:17:25 +00003108 else
3109#ifdef LIBXML_DEBUG_ENABLED
3110 if ((!strcmp(argv[i], "-shell")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003111 (!strcmp(argv[i], "--shell"))) {
3112 shell++;
3113 noout = 1;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003114 } else
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003115#endif
Daniel Veillard652327a2003-09-29 18:02:38 +00003116#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003117 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
3118 copy++;
Daniel Veillard652327a2003-09-29 18:02:38 +00003119 else
3120#endif /* LIBXML_TREE_ENABLED */
3121 if ((!strcmp(argv[i], "-recover")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003122 (!strcmp(argv[i], "--recover"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003123 recovery++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003124 options |= XML_PARSE_RECOVER;
Daniel Veillard8915c152008-08-26 13:05:34 +00003125 } else if ((!strcmp(argv[i], "-huge")) ||
3126 (!strcmp(argv[i], "--huge"))) {
3127 options |= XML_PARSE_HUGE;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003128 } else if ((!strcmp(argv[i], "-noent")) ||
3129 (!strcmp(argv[i], "--noent"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003130 noent++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003131 options |= XML_PARSE_NOENT;
Daniel Veillarddca8cc72003-09-26 13:53:14 +00003132 } else if ((!strcmp(argv[i], "-nsclean")) ||
3133 (!strcmp(argv[i], "--nsclean"))) {
3134 options |= XML_PARSE_NSCLEAN;
3135 } else if ((!strcmp(argv[i], "-nocdata")) ||
3136 (!strcmp(argv[i], "--nocdata"))) {
3137 options |= XML_PARSE_NOCDATA;
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003138 } else if ((!strcmp(argv[i], "-nodict")) ||
3139 (!strcmp(argv[i], "--nodict"))) {
3140 options |= XML_PARSE_NODICT;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003141 } else if ((!strcmp(argv[i], "-version")) ||
Daniel Veillard845cce42002-01-09 11:51:37 +00003142 (!strcmp(argv[i], "--version"))) {
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00003143 showVersion(argv[0]);
Daniel Veillard845cce42002-01-09 11:51:37 +00003144 version = 1;
3145 } else if ((!strcmp(argv[i], "-noout")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003146 (!strcmp(argv[i], "--noout")))
3147 noout++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003148#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003149 else if ((!strcmp(argv[i], "-o")) ||
3150 (!strcmp(argv[i], "-output")) ||
3151 (!strcmp(argv[i], "--output"))) {
3152 i++;
Daniel Veillard6e4f1c02002-04-09 09:55:20 +00003153 output = argv[i];
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003154 }
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003155#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003156 else if ((!strcmp(argv[i], "-htmlout")) ||
3157 (!strcmp(argv[i], "--htmlout")))
3158 htmlout++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003159 else if ((!strcmp(argv[i], "-nowrap")) ||
3160 (!strcmp(argv[i], "--nowrap")))
3161 nowrap++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003162#ifdef LIBXML_HTML_ENABLED
3163 else if ((!strcmp(argv[i], "-html")) ||
3164 (!strcmp(argv[i], "--html"))) {
3165 html++;
3166 }
Daniel Veillard42fd4122003-11-04 08:47:48 +00003167 else if ((!strcmp(argv[i], "-xmlout")) ||
3168 (!strcmp(argv[i], "--xmlout"))) {
3169 xmlout++;
Daniel Veillardf1121c42010-07-26 14:02:42 +02003170 } else if ((!strcmp(argv[i], "-nodefdtd")) ||
3171 (!strcmp(argv[i], "--nodefdtd"))) {
3172 nodefdtd++;
3173 options |= HTML_PARSE_NODEFDTD;
Daniel Veillard42fd4122003-11-04 08:47:48 +00003174 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003175#endif /* LIBXML_HTML_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003176 else if ((!strcmp(argv[i], "-loaddtd")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003177 (!strcmp(argv[i], "--loaddtd"))) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003178 loaddtd++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003179 options |= XML_PARSE_DTDLOAD;
3180 } else if ((!strcmp(argv[i], "-dtdattr")) ||
Daniel Veillard48da9102001-08-07 01:10:10 +00003181 (!strcmp(argv[i], "--dtdattr"))) {
3182 loaddtd++;
3183 dtdattrs++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003184 options |= XML_PARSE_DTDATTR;
Daniel Veillard4432df22003-09-28 18:58:27 +00003185 }
3186#ifdef LIBXML_VALID_ENABLED
3187 else if ((!strcmp(argv[i], "-valid")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003188 (!strcmp(argv[i], "--valid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003189 valid++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003190 options |= XML_PARSE_DTDVALID;
3191 } else if ((!strcmp(argv[i], "-postvalid")) ||
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003192 (!strcmp(argv[i], "--postvalid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003193 postvalid++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003194 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003195 options |= XML_PARSE_DTDLOAD;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003196 } else if ((!strcmp(argv[i], "-dtdvalid")) ||
Daniel Veillardcd429612000-10-11 15:57:05 +00003197 (!strcmp(argv[i], "--dtdvalid"))) {
3198 i++;
3199 dtdvalid = argv[i];
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003200 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003201 options |= XML_PARSE_DTDLOAD;
Daniel Veillard66f68e72003-08-18 16:39:51 +00003202 } else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3203 (!strcmp(argv[i], "--dtdvalidfpi"))) {
3204 i++;
3205 dtdvalidfpi = argv[i];
3206 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003207 options |= XML_PARSE_DTDLOAD;
Daniel Veillardcd429612000-10-11 15:57:05 +00003208 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003209#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard29e43992001-12-13 22:21:58 +00003210 else if ((!strcmp(argv[i], "-dropdtd")) ||
3211 (!strcmp(argv[i], "--dropdtd")))
3212 dropdtd++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003213 else if ((!strcmp(argv[i], "-insert")) ||
3214 (!strcmp(argv[i], "--insert")))
3215 insert++;
Daniel Veillard48b2f892001-02-25 16:11:03 +00003216 else if ((!strcmp(argv[i], "-timing")) ||
3217 (!strcmp(argv[i], "--timing")))
3218 timing++;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00003219 else if ((!strcmp(argv[i], "-auto")) ||
3220 (!strcmp(argv[i], "--auto")))
3221 generate++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003222 else if ((!strcmp(argv[i], "-repeat")) ||
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00003223 (!strcmp(argv[i], "--repeat"))) {
3224 if (repeat)
3225 repeat *= 10;
3226 else
3227 repeat = 100;
Daniel Veillard73b013f2003-09-30 12:36:01 +00003228 }
3229#ifdef LIBXML_PUSH_ENABLED
3230 else if ((!strcmp(argv[i], "-push")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003231 (!strcmp(argv[i], "--push")))
3232 push++;
Daniel Veillard73b013f2003-09-30 12:36:01 +00003233#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillard46e370e2000-07-21 20:32:03 +00003234#ifdef HAVE_SYS_MMAN_H
3235 else if ((!strcmp(argv[i], "-memory")) ||
3236 (!strcmp(argv[i], "--memory")))
3237 memory++;
3238#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +00003239 else if ((!strcmp(argv[i], "-testIO")) ||
3240 (!strcmp(argv[i], "--testIO")))
3241 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003242#ifdef LIBXML_XINCLUDE_ENABLED
3243 else if ((!strcmp(argv[i], "-xinclude")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003244 (!strcmp(argv[i], "--xinclude"))) {
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003245 xinclude++;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003246 options |= XML_PARSE_XINCLUDE;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003247 }
Daniel Veillardc14c3892004-08-16 12:34:50 +00003248 else if ((!strcmp(argv[i], "-noxincludenode")) ||
3249 (!strcmp(argv[i], "--noxincludenode"))) {
3250 xinclude++;
3251 options |= XML_PARSE_XINCLUDE;
3252 options |= XML_PARSE_NOXINCNODE;
3253 }
Daniel Veillard54bd29b2008-08-26 07:26:55 +00003254 else if ((!strcmp(argv[i], "-nofixup-base-uris")) ||
3255 (!strcmp(argv[i], "--nofixup-base-uris"))) {
3256 xinclude++;
3257 options |= XML_PARSE_XINCLUDE;
3258 options |= XML_PARSE_NOBASEFIX;
3259 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003260#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003261#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003262#ifdef HAVE_ZLIB_H
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003263 else if ((!strcmp(argv[i], "-compress")) ||
3264 (!strcmp(argv[i], "--compress"))) {
3265 compress++;
3266 xmlSetCompressMode(9);
3267 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003268#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003269#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003270 else if ((!strcmp(argv[i], "-nowarning")) ||
3271 (!strcmp(argv[i], "--nowarning"))) {
3272 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003273 xmlPedanticParserDefault(0);
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003274 options |= XML_PARSE_NOWARNING;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003275 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003276 else if ((!strcmp(argv[i], "-pedantic")) ||
3277 (!strcmp(argv[i], "--pedantic"))) {
3278 xmlGetWarningsDefaultValue = 1;
3279 xmlPedanticParserDefault(1);
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003280 options |= XML_PARSE_PEDANTIC;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003281 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00003282#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003283 else if ((!strcmp(argv[i], "-debugent")) ||
3284 (!strcmp(argv[i], "--debugent"))) {
3285 debugent++;
3286 xmlParserDebugEntities = 1;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003287 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00003288#endif
Daniel Veillard25048d82004-08-14 22:37:54 +00003289#ifdef LIBXML_C14N_ENABLED
3290 else if ((!strcmp(argv[i], "-c14n")) ||
3291 (!strcmp(argv[i], "--c14n"))) {
3292 canonical++;
3293 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003294 }
Aleksey Sanin83868242009-07-09 10:26:22 +02003295 else if ((!strcmp(argv[i], "-c14n11")) ||
3296 (!strcmp(argv[i], "--c14n11"))) {
3297 canonical_11++;
3298 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003299 }
Aleksey Sanin2650df12005-06-06 17:16:50 +00003300 else if ((!strcmp(argv[i], "-exc-c14n")) ||
3301 (!strcmp(argv[i], "--exc-c14n"))) {
3302 exc_canonical++;
3303 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003304 }
Daniel Veillard25048d82004-08-14 22:37:54 +00003305#endif
Daniel Veillard81418e32001-05-22 15:08:55 +00003306#ifdef LIBXML_CATALOG_ENABLED
3307 else if ((!strcmp(argv[i], "-catalogs")) ||
3308 (!strcmp(argv[i], "--catalogs"))) {
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003309 catalogs++;
3310 } else if ((!strcmp(argv[i], "-nocatalogs")) ||
3311 (!strcmp(argv[i], "--nocatalogs"))) {
3312 nocatalogs++;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003313 }
Daniel Veillard81418e32001-05-22 15:08:55 +00003314#endif
Daniel Veillardbe803962000-06-28 23:40:59 +00003315 else if ((!strcmp(argv[i], "-encode")) ||
3316 (!strcmp(argv[i], "--encode"))) {
3317 i++;
3318 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003319 /*
3320 * OK it's for testing purposes
3321 */
3322 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +00003323 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003324 else if ((!strcmp(argv[i], "-noblanks")) ||
3325 (!strcmp(argv[i], "--noblanks"))) {
3326 noblanks++;
3327 xmlKeepBlanksDefault(0);
Daniel Veillard90493a92001-08-14 14:12:47 +00003328 }
Daniel Veillard87076042004-05-03 22:54:49 +00003329 else if ((!strcmp(argv[i], "-maxmem")) ||
3330 (!strcmp(argv[i], "--maxmem"))) {
3331 i++;
3332 if (sscanf(argv[i], "%d", &maxmem) == 1) {
3333 xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc,
3334 myStrdupFunc);
3335 } else {
3336 maxmem = 0;
3337 }
3338 }
Daniel Veillard90493a92001-08-14 14:12:47 +00003339 else if ((!strcmp(argv[i], "-format")) ||
3340 (!strcmp(argv[i], "--format"))) {
3341 noblanks++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003342#ifdef LIBXML_OUTPUT_ENABLED
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01003343 format = 1;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003344#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard90493a92001-08-14 14:12:47 +00003345 xmlKeepBlanksDefault(0);
Daniel Veillard7704fb12003-01-03 16:19:51 +00003346 }
Adam Spraggd2e62312010-11-03 15:33:40 +01003347 else if ((!strcmp(argv[i], "-pretty")) ||
3348 (!strcmp(argv[i], "--pretty"))) {
3349 i++;
3350#ifdef LIBXML_OUTPUT_ENABLED
3351 format = atoi(argv[i]);
3352#endif /* LIBXML_OUTPUT_ENABLED */
3353 if (format == 1) {
3354 noblanks++;
3355 xmlKeepBlanksDefault(0);
3356 }
3357 }
Daniel Veillard81273902003-09-30 00:43:48 +00003358#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003359 else if ((!strcmp(argv[i], "-stream")) ||
3360 (!strcmp(argv[i], "--stream"))) {
3361 stream++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003362 }
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003363 else if ((!strcmp(argv[i], "-walker")) ||
3364 (!strcmp(argv[i], "--walker"))) {
3365 walker++;
3366 noout++;
3367 }
Daniel Veillard81273902003-09-30 00:43:48 +00003368#endif /* LIBXML_READER_ENABLED */
3369#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +00003370 else if ((!strcmp(argv[i], "-sax1")) ||
3371 (!strcmp(argv[i], "--sax1"))) {
Daniel Veillard023d0ba2009-07-29 11:34:50 +02003372 sax1++;
3373 options |= XML_PARSE_SAX1;
Daniel Veillard07cb8222003-09-10 10:51:05 +00003374 }
Daniel Veillard81273902003-09-30 00:43:48 +00003375#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003376 else if ((!strcmp(argv[i], "-sax")) ||
3377 (!strcmp(argv[i], "--sax"))) {
Daniel Veillard023d0ba2009-07-29 11:34:50 +02003378 sax++;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003379 }
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003380 else if ((!strcmp(argv[i], "-chkregister")) ||
3381 (!strcmp(argv[i], "--chkregister"))) {
Daniel Veillard023d0ba2009-07-29 11:34:50 +02003382 chkregister++;
Daniel Veillard71531f32003-02-05 13:19:53 +00003383#ifdef LIBXML_SCHEMAS_ENABLED
3384 } else if ((!strcmp(argv[i], "-relaxng")) ||
3385 (!strcmp(argv[i], "--relaxng"))) {
3386 i++;
3387 relaxng = argv[i];
3388 noent++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003389 options |= XML_PARSE_NOENT;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003390 } else if ((!strcmp(argv[i], "-schema")) ||
3391 (!strcmp(argv[i], "--schema"))) {
3392 i++;
3393 schema = argv[i];
3394 noent++;
Daniel Veillard71531f32003-02-05 13:19:53 +00003395#endif
Daniel Veillardd4501d72005-07-24 14:27:16 +00003396#ifdef LIBXML_SCHEMATRON_ENABLED
3397 } else if ((!strcmp(argv[i], "-schematron")) ||
3398 (!strcmp(argv[i], "--schematron"))) {
3399 i++;
3400 schematron = argv[i];
3401 noent++;
3402#endif
Daniel Veillarde8b09e42003-05-13 22:14:13 +00003403 } else if ((!strcmp(argv[i], "-nonet")) ||
3404 (!strcmp(argv[i], "--nonet"))) {
Daniel Veillard61b93382003-11-03 14:28:31 +00003405 options |= XML_PARSE_NONET;
Daniel Veillard968d6432006-04-25 16:17:53 +00003406 xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
Daniel Veillard8874b942005-08-25 13:19:21 +00003407 } else if ((!strcmp(argv[i], "-nocompact")) ||
3408 (!strcmp(argv[i], "--nocompact"))) {
3409 options &= ~XML_PARSE_COMPACT;
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003410 } else if ((!strcmp(argv[i], "-load-trace")) ||
3411 (!strcmp(argv[i], "--load-trace"))) {
3412 load_trace++;
3413 } else if ((!strcmp(argv[i], "-path")) ||
3414 (!strcmp(argv[i], "--path"))) {
3415 i++;
3416 parsePath(BAD_CAST argv[i]);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003417#ifdef LIBXML_PATTERN_ENABLED
3418 } else if ((!strcmp(argv[i], "-pattern")) ||
3419 (!strcmp(argv[i], "--pattern"))) {
3420 i++;
3421 pattern = argv[i];
3422#endif
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003423#ifdef LIBXML_XPATH_ENABLED
3424 } else if ((!strcmp(argv[i], "-xpath")) ||
3425 (!strcmp(argv[i], "--xpath"))) {
3426 i++;
3427 noout++;
3428 xpathquery = argv[i];
3429#endif
Daniel Veillard7e5c3f42008-07-29 16:12:31 +00003430 } else if ((!strcmp(argv[i], "-oldxml10")) ||
3431 (!strcmp(argv[i], "--oldxml10"))) {
3432 oldxml10++;
3433 options |= XML_PARSE_OLD10;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003434 } else {
3435 fprintf(stderr, "Unknown option %s\n", argv[i]);
3436 usage(argv[0]);
3437 return(1);
3438 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003439 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003440
3441#ifdef LIBXML_CATALOG_ENABLED
3442 if (nocatalogs == 0) {
3443 if (catalogs) {
3444 const char *catal;
3445
3446 catal = getenv("SGML_CATALOG_FILES");
Daniel Veillard6c5f9d12001-08-25 13:33:14 +00003447 if (catal != NULL) {
3448 xmlLoadCatalogs(catal);
3449 } else {
3450 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
3451 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003452 }
3453 }
3454#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003455
Daniel Veillard81273902003-09-30 00:43:48 +00003456#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +00003457 if (sax1)
3458 xmlSAXDefaultVersion(1);
3459 else
3460 xmlSAXDefaultVersion(2);
Daniel Veillard81273902003-09-30 00:43:48 +00003461#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillard07cb8222003-09-10 10:51:05 +00003462
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003463 if (chkregister) {
3464 xmlRegisterNodeDefault(registerNode);
3465 xmlDeregisterNodeDefault(deregisterNode);
3466 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02003467
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00003468 indent = getenv("XMLLINT_INDENT");
3469 if(indent != NULL) {
3470 xmlTreeIndentString = indent;
3471 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02003472
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003473
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003474 defaultEntityLoader = xmlGetExternalEntityLoader();
3475 xmlSetExternalEntityLoader(xmllintExternalEntityLoader);
3476
Daniel Veillardd9bad132001-07-23 19:39:43 +00003477 xmlLineNumbersDefault(1);
Daniel Veillard48da9102001-08-07 01:10:10 +00003478 if (loaddtd != 0)
3479 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
3480 if (dtdattrs)
3481 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003482 if (noent != 0) xmlSubstituteEntitiesDefault(1);
Daniel Veillard4432df22003-09-28 18:58:27 +00003483#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003484 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
Daniel Veillard4432df22003-09-28 18:58:27 +00003485#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003486 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003487 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003488 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003489 xmlGenericError(xmlGenericErrorContext,
3490 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
3491 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003492 "<html><head><title>%s output</title></head>\n",
3493 argv[0]);
Daniel Veillardf1edb102009-08-10 14:43:18 +02003494 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003495 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
3496 argv[0]);
3497 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003498
Daniel Veillardd4501d72005-07-24 14:27:16 +00003499#ifdef LIBXML_SCHEMATRON_ENABLED
3500 if ((schematron != NULL) && (sax == 0)
3501#ifdef LIBXML_READER_ENABLED
3502 && (stream == 0)
3503#endif /* LIBXML_READER_ENABLED */
3504 ) {
3505 xmlSchematronParserCtxtPtr ctxt;
3506
3507 /* forces loading the DTDs */
Daniel Veillardf1edb102009-08-10 14:43:18 +02003508 xmlLoadExtDtdDefaultValue |= 1;
Daniel Veillardd4501d72005-07-24 14:27:16 +00003509 options |= XML_PARSE_DTDLOAD;
3510 if (timing) {
3511 startTimer();
3512 }
3513 ctxt = xmlSchematronNewParserCtxt(schematron);
3514#if 0
3515 xmlSchematronSetParserErrors(ctxt,
3516 (xmlSchematronValidityErrorFunc) fprintf,
3517 (xmlSchematronValidityWarningFunc) fprintf,
3518 stderr);
3519#endif
3520 wxschematron = xmlSchematronParse(ctxt);
3521 if (wxschematron == NULL) {
3522 xmlGenericError(xmlGenericErrorContext,
3523 "Schematron schema %s failed to compile\n", schematron);
3524 progresult = XMLLINT_ERR_SCHEMACOMP;
3525 schematron = NULL;
3526 }
3527 xmlSchematronFreeParserCtxt(ctxt);
3528 if (timing) {
3529 endTimer("Compiling the schemas");
3530 }
3531 }
3532#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00003533#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003534 if ((relaxng != NULL) && (sax == 0)
Daniel Veillard81273902003-09-30 00:43:48 +00003535#ifdef LIBXML_READER_ENABLED
3536 && (stream == 0)
3537#endif /* LIBXML_READER_ENABLED */
3538 ) {
Daniel Veillard71531f32003-02-05 13:19:53 +00003539 xmlRelaxNGParserCtxtPtr ctxt;
3540
Daniel Veillardce192eb2003-04-16 15:58:05 +00003541 /* forces loading the DTDs */
Daniel Veillardf1edb102009-08-10 14:43:18 +02003542 xmlLoadExtDtdDefaultValue |= 1;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003543 options |= XML_PARSE_DTDLOAD;
Daniel Veillard42f12e92003-03-07 18:32:59 +00003544 if (timing) {
3545 startTimer();
3546 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003547 ctxt = xmlRelaxNGNewParserCtxt(relaxng);
3548 xmlRelaxNGSetParserErrors(ctxt,
3549 (xmlRelaxNGValidityErrorFunc) fprintf,
3550 (xmlRelaxNGValidityWarningFunc) fprintf,
3551 stderr);
3552 relaxngschemas = xmlRelaxNGParse(ctxt);
Daniel Veillardce192eb2003-04-16 15:58:05 +00003553 if (relaxngschemas == NULL) {
3554 xmlGenericError(xmlGenericErrorContext,
3555 "Relax-NG schema %s failed to compile\n", relaxng);
William M. Brack8304d872004-06-08 13:29:32 +00003556 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillardce192eb2003-04-16 15:58:05 +00003557 relaxng = NULL;
3558 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003559 xmlRelaxNGFreeParserCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00003560 if (timing) {
3561 endTimer("Compiling the schemas");
3562 }
Daniel Veillardebe25d42004-03-25 09:35:49 +00003563 } else if ((schema != NULL)
3564#ifdef LIBXML_READER_ENABLED
Daniel Veillardf10ae122005-07-10 19:03:16 +00003565 && (stream == 0)
Daniel Veillardebe25d42004-03-25 09:35:49 +00003566#endif
3567 ) {
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003568 xmlSchemaParserCtxtPtr ctxt;
3569
3570 if (timing) {
3571 startTimer();
3572 }
3573 ctxt = xmlSchemaNewParserCtxt(schema);
3574 xmlSchemaSetParserErrors(ctxt,
3575 (xmlSchemaValidityErrorFunc) fprintf,
3576 (xmlSchemaValidityWarningFunc) fprintf,
3577 stderr);
3578 wxschemas = xmlSchemaParse(ctxt);
3579 if (wxschemas == NULL) {
3580 xmlGenericError(xmlGenericErrorContext,
3581 "WXS schema %s failed to compile\n", schema);
William M. Brack8304d872004-06-08 13:29:32 +00003582 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003583 schema = NULL;
3584 }
3585 xmlSchemaFreeParserCtxt(ctxt);
3586 if (timing) {
3587 endTimer("Compiling the schemas");
3588 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003589 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003590#endif /* LIBXML_SCHEMAS_ENABLED */
3591#ifdef LIBXML_PATTERN_ENABLED
Daniel Veillard39e5c892005-07-03 22:48:50 +00003592 if ((pattern != NULL)
Daniel Veillardc9352532005-07-04 14:25:34 +00003593#ifdef LIBXML_READER_ENABLED
Daniel Veillard39e5c892005-07-03 22:48:50 +00003594 && (walker == 0)
3595#endif
3596 ) {
Daniel Veillardffa7b7e2003-12-05 16:10:21 +00003597 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003598 if (patternc == NULL) {
3599 xmlGenericError(xmlGenericErrorContext,
3600 "Pattern %s failed to compile\n", pattern);
William M. Brack8304d872004-06-08 13:29:32 +00003601 progresult = XMLLINT_ERR_SCHEMAPAT;
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003602 pattern = NULL;
3603 }
3604 }
3605#endif /* LIBXML_PATTERN_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003606 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +00003607 if ((!strcmp(argv[i], "-encode")) ||
3608 (!strcmp(argv[i], "--encode"))) {
3609 i++;
3610 continue;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003611 } else if ((!strcmp(argv[i], "-o")) ||
3612 (!strcmp(argv[i], "-output")) ||
3613 (!strcmp(argv[i], "--output"))) {
3614 i++;
3615 continue;
Daniel Veillardbe803962000-06-28 23:40:59 +00003616 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003617#ifdef LIBXML_VALID_ENABLED
Daniel Veillardcd429612000-10-11 15:57:05 +00003618 if ((!strcmp(argv[i], "-dtdvalid")) ||
3619 (!strcmp(argv[i], "--dtdvalid"))) {
3620 i++;
3621 continue;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003622 }
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003623 if ((!strcmp(argv[i], "-path")) ||
3624 (!strcmp(argv[i], "--path"))) {
3625 i++;
3626 continue;
Daniel Veillardcd429612000-10-11 15:57:05 +00003627 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00003628 if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3629 (!strcmp(argv[i], "--dtdvalidfpi"))) {
3630 i++;
3631 continue;
3632 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003633#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard71531f32003-02-05 13:19:53 +00003634 if ((!strcmp(argv[i], "-relaxng")) ||
3635 (!strcmp(argv[i], "--relaxng"))) {
3636 i++;
3637 continue;
3638 }
Daniel Veillard87076042004-05-03 22:54:49 +00003639 if ((!strcmp(argv[i], "-maxmem")) ||
3640 (!strcmp(argv[i], "--maxmem"))) {
3641 i++;
3642 continue;
3643 }
Adam Spraggd2e62312010-11-03 15:33:40 +01003644 if ((!strcmp(argv[i], "-pretty")) ||
3645 (!strcmp(argv[i], "--pretty"))) {
3646 i++;
3647 continue;
3648 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003649 if ((!strcmp(argv[i], "-schema")) ||
3650 (!strcmp(argv[i], "--schema"))) {
3651 i++;
3652 continue;
3653 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00003654 if ((!strcmp(argv[i], "-schematron")) ||
3655 (!strcmp(argv[i], "--schematron"))) {
3656 i++;
3657 continue;
3658 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003659#ifdef LIBXML_PATTERN_ENABLED
3660 if ((!strcmp(argv[i], "-pattern")) ||
3661 (!strcmp(argv[i], "--pattern"))) {
3662 i++;
3663 continue;
3664 }
3665#endif
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003666#ifdef LIBXML_XPATH_ENABLED
3667 if ((!strcmp(argv[i], "-xpath")) ||
3668 (!strcmp(argv[i], "--xpath"))) {
3669 i++;
3670 continue;
3671 }
3672#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00003673 if ((timing) && (repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00003674 startTimer();
Daniel Veillardcbaf3992001-12-31 16:16:02 +00003675 /* Remember file names. "-" means stdin. <sven@zen.org> */
Daniel Veillard4a6845d2001-01-03 13:32:39 +00003676 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003677 if (repeat) {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003678 xmlParserCtxtPtr ctxt = NULL;
3679
3680 for (acount = 0;acount < repeat;acount++) {
Daniel Veillard81273902003-09-30 00:43:48 +00003681#ifdef LIBXML_READER_ENABLED
Daniel Veillard198c1bf2003-10-20 17:07:41 +00003682 if (stream != 0) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00003683 streamFile(argv[i]);
Daniel Veillard198c1bf2003-10-20 17:07:41 +00003684 } else {
Daniel Veillard81273902003-09-30 00:43:48 +00003685#endif /* LIBXML_READER_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003686 if (sax) {
3687 testSAX(argv[i]);
3688 } else {
3689 if (ctxt == NULL)
3690 ctxt = xmlNewParserCtxt();
3691 parseAndPrintFile(argv[i], ctxt);
3692 }
Daniel Veillard81273902003-09-30 00:43:48 +00003693#ifdef LIBXML_READER_ENABLED
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003694 }
Daniel Veillard81273902003-09-30 00:43:48 +00003695#endif /* LIBXML_READER_ENABLED */
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003696 }
3697 if (ctxt != NULL)
3698 xmlFreeParserCtxt(ctxt);
Daniel Veillard7704fb12003-01-03 16:19:51 +00003699 } else {
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003700 nbregister = 0;
3701
Daniel Veillard81273902003-09-30 00:43:48 +00003702#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003703 if (stream != 0)
3704 streamFile(argv[i]);
3705 else
Daniel Veillard81273902003-09-30 00:43:48 +00003706#endif /* LIBXML_READER_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003707 if (sax) {
3708 testSAX(argv[i]);
3709 } else {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003710 parseAndPrintFile(argv[i], NULL);
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003711 }
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003712
3713 if ((chkregister) && (nbregister != 0)) {
3714 fprintf(stderr, "Registration count off: %d\n", nbregister);
William M. Brack8304d872004-06-08 13:29:32 +00003715 progresult = XMLLINT_ERR_RDREGIS;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003716 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00003717 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003718 files ++;
Daniel Veillarda7866932001-12-04 13:14:44 +00003719 if ((timing) && (repeat)) {
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00003720 endTimer("%d iterations", repeat);
Daniel Veillarda7866932001-12-04 13:14:44 +00003721 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00003722 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003723 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02003724 if (generate)
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003725 parseAndPrintFile(NULL, NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003726 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003727 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003728 }
Daniel Veillard845cce42002-01-09 11:51:37 +00003729 if ((files == 0) && (!generate) && (version == 0)) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003730 usage(argv[0]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003731 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00003732#ifdef LIBXML_SCHEMATRON_ENABLED
3733 if (wxschematron != NULL)
3734 xmlSchematronFree(wxschematron);
3735#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00003736#ifdef LIBXML_SCHEMAS_ENABLED
3737 if (relaxngschemas != NULL)
3738 xmlRelaxNGFree(relaxngschemas);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003739 if (wxschemas != NULL)
3740 xmlSchemaFree(wxschemas);
Daniel Veillard71531f32003-02-05 13:19:53 +00003741 xmlRelaxNGCleanupTypes();
3742#endif
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003743#ifdef LIBXML_PATTERN_ENABLED
3744 if (patternc != NULL)
3745 xmlFreePattern(patternc);
3746#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003747 xmlCleanupParser();
3748 xmlMemoryDump();
3749
Daniel Veillardf7cd4812001-02-23 18:44:52 +00003750 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003751}
Daniel Veillard88a172f2000-08-04 18:23:10 +00003752