blob: 39d713815afed77c29a64284793164047f5967f4 [file] [log] [blame]
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001/*
2 * xmllint.c : a small tester program for XML input.
3 *
4 * See Copyright for the status of this software.
5 *
Daniel Veillardc5d64342001-06-24 12:13:24 +00006 * daniel@veillard.com
Daniel Veillardce8b83b2000-04-05 18:38:42 +00007 */
8
Bjorn Reese70a9da52001-04-21 16:57:29 +00009#include "libxml.h"
Daniel Veillardce8b83b2000-04-05 18:38:42 +000010
Daniel Veillardce8b83b2000-04-05 18:38:42 +000011#include <string.h>
Daniel Veillardce8b83b2000-04-05 18:38:42 +000012#include <stdarg.h>
Daniel Veillard8a1b1852003-01-05 22:37:17 +000013#include <assert.h>
14
Daniel Veillard3c5ed912002-01-08 10:36:16 +000015#if defined (_WIN32) && !defined(__CYGWIN__)
Daniel Veillard07cb8222003-09-10 10:51:05 +000016#if defined (_MSC_VER) || defined(__BORLANDC__)
Daniel Veillard2d90de42001-04-16 17:46:18 +000017#include <winsock2.h>
18#pragma comment(lib, "ws2_32.lib")
19#define gettimeofday(p1,p2)
20#endif /* _MSC_VER */
Igor Zlatkovic19b87642003-08-28 12:32:04 +000021#endif /* _WIN32 */
22
Daniel Veillarded472f32001-12-13 08:48:14 +000023#ifdef HAVE_SYS_TIME_H
Daniel Veillard48b2f892001-02-25 16:11:03 +000024#include <sys/time.h>
Daniel Veillarded472f32001-12-13 08:48:14 +000025#endif
Daniel Veillard01db67c2001-12-18 07:09:59 +000026#ifdef HAVE_TIME_H
27#include <time.h>
28#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +000029
Daniel Veillard1638a472003-08-14 01:23:25 +000030#ifdef __MINGW32__
31#define _WINSOCKAPI_
32#include <wsockcompat.h>
33#include <winsock2.h>
Daniel Veillardc284c642005-03-31 10:24:24 +000034#undef XML_SOCKLEN_T
35#define XML_SOCKLEN_T unsigned int
Daniel Veillard1638a472003-08-14 01:23:25 +000036#endif
37
Daniel Veillard90bc3712002-03-07 15:12:58 +000038#ifdef HAVE_SYS_TIMEB_H
39#include <sys/timeb.h>
40#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000041
42#ifdef HAVE_SYS_TYPES_H
43#include <sys/types.h>
44#endif
45#ifdef HAVE_SYS_STAT_H
46#include <sys/stat.h>
47#endif
48#ifdef HAVE_FCNTL_H
49#include <fcntl.h>
50#endif
51#ifdef HAVE_UNISTD_H
52#include <unistd.h>
53#endif
Daniel Veillard46e370e2000-07-21 20:32:03 +000054#ifdef HAVE_SYS_MMAN_H
55#include <sys/mman.h>
Daniel Veillard87b95392000-08-12 21:12:04 +000056/* seems needed for Solaris */
57#ifndef MAP_FAILED
58#define MAP_FAILED ((void *) -1)
59#endif
Daniel Veillard46e370e2000-07-21 20:32:03 +000060#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000061#ifdef HAVE_STDLIB_H
62#include <stdlib.h>
63#endif
64#ifdef HAVE_LIBREADLINE
65#include <readline/readline.h>
66#ifdef HAVE_LIBHISTORY
67#include <readline/history.h>
68#endif
69#endif
70
71#include <libxml/xmlmemory.h>
72#include <libxml/parser.h>
73#include <libxml/parserInternals.h>
74#include <libxml/HTMLparser.h>
75#include <libxml/HTMLtree.h>
76#include <libxml/tree.h>
77#include <libxml/xpath.h>
78#include <libxml/debugXML.h>
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +000079#include <libxml/xmlerror.h>
Daniel Veillard9e8bfae2000-11-06 16:43:11 +000080#ifdef LIBXML_XINCLUDE_ENABLED
81#include <libxml/xinclude.h>
82#endif
Daniel Veillard81418e32001-05-22 15:08:55 +000083#ifdef LIBXML_CATALOG_ENABLED
84#include <libxml/catalog.h>
85#endif
Daniel Veillard3c01b1d2001-10-17 15:58:35 +000086#include <libxml/globals.h>
Daniel Veillard7704fb12003-01-03 16:19:51 +000087#include <libxml/xmlreader.h>
Daniel Veillardd4501d72005-07-24 14:27:16 +000088#ifdef LIBXML_SCHEMATRON_ENABLED
89#include <libxml/schematron.h>
90#endif
Daniel Veillard71531f32003-02-05 13:19:53 +000091#ifdef LIBXML_SCHEMAS_ENABLED
92#include <libxml/relaxng.h>
Daniel Veillard75bb3bb2003-05-12 15:25:56 +000093#include <libxml/xmlschemas.h>
Daniel Veillard71531f32003-02-05 13:19:53 +000094#endif
Daniel Veillardb3de70c2003-12-02 22:32:15 +000095#ifdef LIBXML_PATTERN_ENABLED
96#include <libxml/pattern.h>
97#endif
Daniel Veillard6ebf3c42004-08-22 13:11:39 +000098#ifdef LIBXML_C14N_ENABLED
99#include <libxml/c14n.h>
100#endif
Daniel Veillarddab39b52006-10-16 23:22:10 +0000101#ifdef LIBXML_OUTPUT_ENABLED
102#include <libxml/xmlsave.h>
103#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000104
Daniel Veillard3be27512003-01-26 19:49:04 +0000105#ifndef XML_XML_DEFAULT_CATALOG
106#define XML_XML_DEFAULT_CATALOG "file:///etc/xml/catalog"
107#endif
108
William M. Brack8304d872004-06-08 13:29:32 +0000109typedef enum {
110 XMLLINT_RETURN_OK = 0, /* No error */
Daniel Veillard1934b0c2009-10-07 10:25:06 +0200111 XMLLINT_ERR_UNCLASS = 1, /* Unclassified */
112 XMLLINT_ERR_DTD = 2, /* Error in DTD */
113 XMLLINT_ERR_VALID = 3, /* Validation error */
114 XMLLINT_ERR_RDFILE = 4, /* CtxtReadFile error */
115 XMLLINT_ERR_SCHEMACOMP = 5, /* Schema compilation */
116 XMLLINT_ERR_OUT = 6, /* Error writing output */
117 XMLLINT_ERR_SCHEMAPAT = 7, /* Error in schema pattern */
118 XMLLINT_ERR_RDREGIS = 8, /* Error in Reader registration */
119 XMLLINT_ERR_MEM = 9, /* Out of memory error */
120 XMLLINT_ERR_XPATH = 10 /* XPath evaluation error */
William M. Brack8304d872004-06-08 13:29:32 +0000121} xmllintReturnCode;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000122#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000123static int shell = 0;
124static int debugent = 0;
125#endif
Daniel Veillard8326e732003-01-07 00:19:07 +0000126static int debug = 0;
Daniel Veillard87076042004-05-03 22:54:49 +0000127static int maxmem = 0;
Daniel Veillard652327a2003-09-29 18:02:38 +0000128#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000129static int copy = 0;
Daniel Veillard652327a2003-09-29 18:02:38 +0000130#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000131static int recovery = 0;
132static int noent = 0;
Daniel Veillardc62efc82011-05-16 16:03:50 +0800133static int noenc = 0;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +0000134static int noblanks = 0;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000135static int noout = 0;
136static int nowrap = 0;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +0000137#ifdef LIBXML_OUTPUT_ENABLED
138static int format = 0;
139static const char *output = NULL;
140static int compress = 0;
Daniel Veillarddab39b52006-10-16 23:22:10 +0000141static int oldout = 0;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +0000142#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard4432df22003-09-28 18:58:27 +0000143#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000144static int valid = 0;
145static int postvalid = 0;
Daniel Veillardcd429612000-10-11 15:57:05 +0000146static char * dtdvalid = NULL;
Daniel Veillard66f68e72003-08-18 16:39:51 +0000147static char * dtdvalidfpi = NULL;
Daniel Veillard4432df22003-09-28 18:58:27 +0000148#endif
Daniel Veillard71531f32003-02-05 13:19:53 +0000149#ifdef LIBXML_SCHEMAS_ENABLED
150static char * relaxng = NULL;
151static xmlRelaxNGPtr relaxngschemas = NULL;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +0000152static char * schema = NULL;
153static xmlSchemaPtr wxschemas = NULL;
Daniel Veillard71531f32003-02-05 13:19:53 +0000154#endif
Daniel Veillard8c6e6532005-09-08 21:39:47 +0000155#ifdef LIBXML_SCHEMATRON_ENABLED
Daniel Veillardd4501d72005-07-24 14:27:16 +0000156static char * schematron = NULL;
157static xmlSchematronPtr wxschematron = NULL;
158#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000159static int repeat = 0;
160static int insert = 0;
Daniel Veillard656ce942004-04-30 23:11:45 +0000161#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000162static int html = 0;
Daniel Veillard42fd4122003-11-04 08:47:48 +0000163static int xmlout = 0;
Daniel Veillard4432df22003-09-28 18:58:27 +0000164#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000165static int htmlout = 0;
Daniel Veillardf1121c42010-07-26 14:02:42 +0200166#if defined(LIBXML_HTML_ENABLED)
167static int nodefdtd = 0;
168#endif
Daniel Veillard73b013f2003-09-30 12:36:01 +0000169#ifdef LIBXML_PUSH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000170static int push = 0;
Daniel Veillard73b013f2003-09-30 12:36:01 +0000171#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillard46e370e2000-07-21 20:32:03 +0000172#ifdef HAVE_SYS_MMAN_H
173static int memory = 0;
174#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +0000175static int testIO = 0;
Daniel Veillardbe803962000-06-28 23:40:59 +0000176static char *encoding = NULL;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000177#ifdef LIBXML_XINCLUDE_ENABLED
178static int xinclude = 0;
179#endif
Daniel Veillard48da9102001-08-07 01:10:10 +0000180static int dtdattrs = 0;
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000181static int loaddtd = 0;
William M. Brack8304d872004-06-08 13:29:32 +0000182static xmllintReturnCode progresult = XMLLINT_RETURN_OK;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000183static int timing = 0;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000184static int generate = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000185static int dropdtd = 0;
Daniel Veillarde2940dd2001-08-22 00:06:49 +0000186#ifdef LIBXML_CATALOG_ENABLED
187static int catalogs = 0;
188static int nocatalogs = 0;
189#endif
Daniel Veillard25048d82004-08-14 22:37:54 +0000190#ifdef LIBXML_C14N_ENABLED
191static int canonical = 0;
Aleksey Sanin83868242009-07-09 10:26:22 +0200192static int canonical_11 = 0;
Aleksey Sanin2650df12005-06-06 17:16:50 +0000193static int exc_canonical = 0;
Daniel Veillard25048d82004-08-14 22:37:54 +0000194#endif
Daniel Veillard81273902003-09-30 00:43:48 +0000195#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +0000196static int stream = 0;
Daniel Veillard7899c5c2003-11-03 12:31:38 +0000197static int walker = 0;
Daniel Veillard81273902003-09-30 00:43:48 +0000198#endif /* LIBXML_READER_ENABLED */
Daniel Veillard8a1b1852003-01-05 22:37:17 +0000199static int chkregister = 0;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +0000200static int nbregister = 0;
Daniel Veillard81273902003-09-30 00:43:48 +0000201#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +0000202static int sax1 = 0;
Daniel Veillard81273902003-09-30 00:43:48 +0000203#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillardb3de70c2003-12-02 22:32:15 +0000204#ifdef LIBXML_PATTERN_ENABLED
205static const char *pattern = NULL;
206static xmlPatternPtr patternc = NULL;
Daniel Veillard2fc6df92005-01-30 18:42:55 +0000207static xmlStreamCtxtPtr patstream = NULL;
Daniel Veillardb3de70c2003-12-02 22:32:15 +0000208#endif
Daniel Veillard1934b0c2009-10-07 10:25:06 +0200209#ifdef LIBXML_XPATH_ENABLED
210static const char *xpathquery = NULL;
211#endif
Daniel Veillard8874b942005-08-25 13:19:21 +0000212static int options = XML_PARSE_COMPACT;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000213static int sax = 0;
Daniel Veillard7e5c3f42008-07-29 16:12:31 +0000214static int oldxml10 = 0;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +0000215
Daniel Veillard87076042004-05-03 22:54:49 +0000216/************************************************************************
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000217 * *
218 * Entity loading control and customization. *
219 * *
220 ************************************************************************/
221#define MAX_PATHS 64
Daniel Veillarded121382007-04-17 12:33:19 +0000222#ifdef _WIN32
223# define PATH_SEPARATOR ';'
224#else
225# define PATH_SEPARATOR ':'
226#endif
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000227static xmlChar *paths[MAX_PATHS + 1];
228static int nbpaths = 0;
229static int load_trace = 0;
230
231static
232void parsePath(const xmlChar *path) {
233 const xmlChar *cur;
234
235 if (path == NULL)
236 return;
237 while (*path != 0) {
238 if (nbpaths >= MAX_PATHS) {
239 fprintf(stderr, "MAX_PATHS reached: too many paths\n");
240 return;
241 }
242 cur = path;
Daniel Veillarded121382007-04-17 12:33:19 +0000243 while ((*cur == ' ') || (*cur == PATH_SEPARATOR))
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000244 cur++;
245 path = cur;
Daniel Veillarded121382007-04-17 12:33:19 +0000246 while ((*cur != 0) && (*cur != ' ') && (*cur != PATH_SEPARATOR))
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000247 cur++;
248 if (cur != path) {
249 paths[nbpaths] = xmlStrndup(path, cur - path);
250 if (paths[nbpaths] != NULL)
251 nbpaths++;
252 path = cur;
253 }
254 }
255}
256
Daniel Veillard24505b02005-07-28 23:49:35 +0000257static xmlExternalEntityLoader defaultEntityLoader = NULL;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000258
Daniel Veillardf1edb102009-08-10 14:43:18 +0200259static xmlParserInputPtr
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000260xmllintExternalEntityLoader(const char *URL, const char *ID,
261 xmlParserCtxtPtr ctxt) {
262 xmlParserInputPtr ret;
263 warningSAXFunc warning = NULL;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000264 errorSAXFunc err = NULL;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000265
266 int i;
267 const char *lastsegment = URL;
268 const char *iter = URL;
269
Daniel Veillard5608b172008-01-11 06:53:15 +0000270 if ((nbpaths > 0) && (iter != NULL)) {
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000271 while (*iter != 0) {
272 if (*iter == '/')
273 lastsegment = iter + 1;
274 iter++;
275 }
276 }
277
278 if ((ctxt != NULL) && (ctxt->sax != NULL)) {
279 warning = ctxt->sax->warning;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000280 err = ctxt->sax->error;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000281 ctxt->sax->warning = NULL;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000282 ctxt->sax->error = NULL;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000283 }
284
285 if (defaultEntityLoader != NULL) {
286 ret = defaultEntityLoader(URL, ID, ctxt);
287 if (ret != NULL) {
288 if (warning != NULL)
289 ctxt->sax->warning = warning;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000290 if (err != NULL)
291 ctxt->sax->error = err;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000292 if (load_trace) {
293 fprintf \
294 (stderr,
295 "Loaded URL=\"%s\" ID=\"%s\"\n",
296 URL ? URL : "(null)",
297 ID ? ID : "(null)");
298 }
299 return(ret);
300 }
301 }
302 for (i = 0;i < nbpaths;i++) {
303 xmlChar *newURL;
304
305 newURL = xmlStrdup((const xmlChar *) paths[i]);
306 newURL = xmlStrcat(newURL, (const xmlChar *) "/");
307 newURL = xmlStrcat(newURL, (const xmlChar *) lastsegment);
308 if (newURL != NULL) {
309 ret = defaultEntityLoader((const char *)newURL, ID, ctxt);
310 if (ret != NULL) {
311 if (warning != NULL)
312 ctxt->sax->warning = warning;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000313 if (err != NULL)
314 ctxt->sax->error = err;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000315 if (load_trace) {
316 fprintf \
Daniel Veillardf1edb102009-08-10 14:43:18 +0200317 (stderr,
318 "Loaded URL=\"%s\" ID=\"%s\"\n",
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000319 newURL,
Daniel Veillardf1edb102009-08-10 14:43:18 +0200320 ID ? ID : "(null)");
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000321 }
322 xmlFree(newURL);
323 return(ret);
324 }
325 xmlFree(newURL);
326 }
327 }
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000328 if (err != NULL)
329 ctxt->sax->error = err;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000330 if (warning != NULL) {
331 ctxt->sax->warning = warning;
332 if (URL != NULL)
333 warning(ctxt, "failed to load external entity \"%s\"\n", URL);
334 else if (ID != NULL)
335 warning(ctxt, "failed to load external entity \"%s\"\n", ID);
336 }
337 return(NULL);
338}
339/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +0200340 * *
Daniel Veillard87076042004-05-03 22:54:49 +0000341 * Memory allocation consumption debugging *
Daniel Veillardf1edb102009-08-10 14:43:18 +0200342 * *
Daniel Veillard87076042004-05-03 22:54:49 +0000343 ************************************************************************/
344
Daniel Veillard3af3b592004-05-05 19:22:30 +0000345static void
346OOM(void)
347{
Daniel Veillard87076042004-05-03 22:54:49 +0000348 fprintf(stderr, "Ran out of memory needs > %d bytes\n", maxmem);
William M. Brack8304d872004-06-08 13:29:32 +0000349 progresult = XMLLINT_ERR_MEM;
Daniel Veillard87076042004-05-03 22:54:49 +0000350}
351
Daniel Veillard3af3b592004-05-05 19:22:30 +0000352static void
353myFreeFunc(void *mem)
354{
Daniel Veillard87076042004-05-03 22:54:49 +0000355 xmlMemFree(mem);
356}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000357static void *
358myMallocFunc(size_t size)
359{
Daniel Veillard87076042004-05-03 22:54:49 +0000360 void *ret;
361
362 ret = xmlMemMalloc(size);
363 if (ret != NULL) {
364 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000365 OOM();
366 xmlMemFree(ret);
367 return (NULL);
368 }
Daniel Veillard87076042004-05-03 22:54:49 +0000369 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000370 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000371}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000372static void *
373myReallocFunc(void *mem, size_t size)
374{
Daniel Veillard87076042004-05-03 22:54:49 +0000375 void *ret;
376
377 ret = xmlMemRealloc(mem, size);
378 if (ret != NULL) {
379 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000380 OOM();
381 xmlMemFree(ret);
382 return (NULL);
383 }
Daniel Veillard87076042004-05-03 22:54:49 +0000384 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000385 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000386}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000387static char *
388myStrdupFunc(const char *str)
389{
Daniel Veillard87076042004-05-03 22:54:49 +0000390 char *ret;
391
392 ret = xmlMemoryStrdup(str);
393 if (ret != NULL) {
394 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000395 OOM();
396 xmlFree(ret);
397 return (NULL);
398 }
Daniel Veillard87076042004-05-03 22:54:49 +0000399 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000400 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000401}
Daniel Veillard87076042004-05-03 22:54:49 +0000402/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +0200403 * *
Daniel Veillard87076042004-05-03 22:54:49 +0000404 * Internal timing routines to remove the necessity to have *
405 * unix-specific function calls. *
Daniel Veillardf1edb102009-08-10 14:43:18 +0200406 * *
Daniel Veillard87076042004-05-03 22:54:49 +0000407 ************************************************************************/
Daniel Veillard01db67c2001-12-18 07:09:59 +0000408
Daniel Veillardf1edb102009-08-10 14:43:18 +0200409#ifndef HAVE_GETTIMEOFDAY
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000410#ifdef HAVE_SYS_TIMEB_H
411#ifdef HAVE_SYS_TIME_H
412#ifdef HAVE_FTIME
413
Daniel Veillard01c13b52002-12-10 15:19:08 +0000414static int
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000415my_gettimeofday(struct timeval *tvp, void *tzp)
416{
417 struct timeb timebuffer;
418
419 ftime(&timebuffer);
420 if (tvp) {
421 tvp->tv_sec = timebuffer.time;
422 tvp->tv_usec = timebuffer.millitm * 1000L;
423 }
424 return (0);
425}
426#define HAVE_GETTIMEOFDAY 1
427#define gettimeofday my_gettimeofday
428
429#endif /* HAVE_FTIME */
430#endif /* HAVE_SYS_TIME_H */
431#endif /* HAVE_SYS_TIMEB_H */
432#endif /* !HAVE_GETTIMEOFDAY */
433
Daniel Veillard01db67c2001-12-18 07:09:59 +0000434#if defined(HAVE_GETTIMEOFDAY)
435static struct timeval begin, end;
436
437/*
438 * startTimer: call where you want to start timing
439 */
440static void
441startTimer(void)
442{
443 gettimeofday(&begin, NULL);
444}
445
446/*
447 * endTimer: call where you want to stop timing and to print out a
448 * message about the timing performed; format is a printf
449 * type argument
450 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000451static void XMLCDECL
Daniel Veillard118aed72002-09-24 14:13:13 +0000452endTimer(const char *fmt, ...)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000453{
454 long msec;
455 va_list ap;
456
457 gettimeofday(&end, NULL);
458 msec = end.tv_sec - begin.tv_sec;
459 msec *= 1000;
460 msec += (end.tv_usec - begin.tv_usec) / 1000;
461
462#ifndef HAVE_STDARG_H
463#error "endTimer required stdarg functions"
464#endif
Daniel Veillard118aed72002-09-24 14:13:13 +0000465 va_start(ap, fmt);
466 vfprintf(stderr, fmt, ap);
Daniel Veillard01db67c2001-12-18 07:09:59 +0000467 va_end(ap);
468
469 fprintf(stderr, " took %ld ms\n", msec);
470}
471#elif defined(HAVE_TIME_H)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000472/*
473 * No gettimeofday function, so we have to make do with calling clock.
474 * This is obviously less accurate, but there's little we can do about
475 * that.
476 */
Daniel Veillard90bc3712002-03-07 15:12:58 +0000477#ifndef CLOCKS_PER_SEC
478#define CLOCKS_PER_SEC 100
479#endif
Daniel Veillard01db67c2001-12-18 07:09:59 +0000480
481static clock_t begin, end;
482static void
483startTimer(void)
484{
485 begin = clock();
486}
Daniel Veillardffa3c742005-07-21 13:24:09 +0000487static void XMLCDECL
Daniel Veillard01db67c2001-12-18 07:09:59 +0000488endTimer(const char *fmt, ...)
489{
490 long msec;
491 va_list ap;
492
493 end = clock();
494 msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
495
496#ifndef HAVE_STDARG_H
497#error "endTimer required stdarg functions"
498#endif
499 va_start(ap, fmt);
500 vfprintf(stderr, fmt, ap);
501 va_end(ap);
502 fprintf(stderr, " took %ld ms\n", msec);
503}
504#else
505
506/*
507 * We don't have a gettimeofday or time.h, so we just don't do timing
508 */
509static void
510startTimer(void)
511{
512 /*
513 * Do nothing
514 */
515}
Daniel Veillardffa3c742005-07-21 13:24:09 +0000516static void XMLCDECL
Daniel Veillard01db67c2001-12-18 07:09:59 +0000517endTimer(char *format, ...)
518{
519 /*
520 * We cannot do anything because we don't have a timing function
521 */
522#ifdef HAVE_STDARG_H
523 va_start(ap, format);
524 vfprintf(stderr, format, ap);
525 va_end(ap);
526 fprintf(stderr, " was not timed\n", msec);
527#else
528 /* We don't have gettimeofday, time or stdarg.h, what crazy world is
529 * this ?!
530 */
531#endif
532}
533#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000534/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +0200535 * *
536 * HTML ouput *
537 * *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000538 ************************************************************************/
Daniel Veillard24505b02005-07-28 23:49:35 +0000539static char buffer[50000];
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000540
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000541static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000542xmlHTMLEncodeSend(void) {
543 char *result;
544
545 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
546 if (result) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000547 xmlGenericError(xmlGenericErrorContext, "%s", result);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000548 xmlFree(result);
549 }
550 buffer[0] = 0;
551}
552
553/**
554 * xmlHTMLPrintFileInfo:
555 * @input: an xmlParserInputPtr input
Daniel Veillardf1edb102009-08-10 14:43:18 +0200556 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000557 * Displays the associated file and line informations for the current input
558 */
559
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000560static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000561xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000562 int len;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000563 xmlGenericError(xmlGenericErrorContext, "<p>");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000564
565 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000566 if (input != NULL) {
567 if (input->filename) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000568 snprintf(&buffer[len], sizeof(buffer) - len, "%s:%d: ", input->filename,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000569 input->line);
570 } else {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000571 snprintf(&buffer[len], sizeof(buffer) - len, "Entity: line %d: ", input->line);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000572 }
573 }
574 xmlHTMLEncodeSend();
575}
576
577/**
578 * xmlHTMLPrintFileContext:
579 * @input: an xmlParserInputPtr input
Daniel Veillardf1edb102009-08-10 14:43:18 +0200580 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000581 * Displays current context within the input content for error tracking
582 */
583
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000584static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000585xmlHTMLPrintFileContext(xmlParserInputPtr input) {
586 const xmlChar *cur, *base;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000587 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000588 int n;
589
590 if (input == NULL) return;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000591 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000592 cur = input->cur;
593 base = input->base;
594 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
595 cur--;
596 }
597 n = 0;
598 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
599 cur--;
600 if ((*cur == '\n') || (*cur == '\r')) cur++;
601 base = cur;
602 n = 0;
603 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000604 len = strlen(buffer);
Daniel Veillardf1edb102009-08-10 14:43:18 +0200605 snprintf(&buffer[len], sizeof(buffer) - len, "%c",
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000606 (unsigned char) *cur++);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000607 n++;
608 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000609 len = strlen(buffer);
610 snprintf(&buffer[len], sizeof(buffer) - len, "\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000611 cur = input->cur;
612 while ((*cur == '\n') || (*cur == '\r'))
613 cur--;
614 n = 0;
615 while ((cur != base) && (n++ < 80)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000616 len = strlen(buffer);
617 snprintf(&buffer[len], sizeof(buffer) - len, " ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000618 base++;
619 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000620 len = strlen(buffer);
621 snprintf(&buffer[len], sizeof(buffer) - len, "^\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000622 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000623 xmlGenericError(xmlGenericErrorContext, "</pre>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000624}
625
626/**
627 * xmlHTMLError:
628 * @ctx: an XML parser context
629 * @msg: the message to display/transmit
630 * @...: extra parameters for the message display
Daniel Veillardf1edb102009-08-10 14:43:18 +0200631 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000632 * Display and format an error messages, gives file, line, position and
633 * extra parameters.
634 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000635static void XMLCDECL
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000636xmlHTMLError(void *ctx, const char *msg, ...)
637{
638 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
639 xmlParserInputPtr input;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000640 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000641 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000642
643 buffer[0] = 0;
644 input = ctxt->input;
645 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000646 input = ctxt->inputTab[ctxt->inputNr - 2];
647 }
Daniel Veillardf1edb102009-08-10 14:43:18 +0200648
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000649 xmlHTMLPrintFileInfo(input);
650
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000651 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000652 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000653 len = strlen(buffer);
654 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000655 va_end(args);
656 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000657 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000658
659 xmlHTMLPrintFileContext(input);
660 xmlHTMLEncodeSend();
661}
662
663/**
664 * xmlHTMLWarning:
665 * @ctx: an XML parser context
666 * @msg: the message to display/transmit
667 * @...: extra parameters for the message display
Daniel Veillardf1edb102009-08-10 14:43:18 +0200668 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000669 * Display and format a warning messages, gives file, line, position and
670 * extra parameters.
671 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000672static void XMLCDECL
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000673xmlHTMLWarning(void *ctx, const char *msg, ...)
674{
675 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
676 xmlParserInputPtr input;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000677 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000678 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000679
680 buffer[0] = 0;
681 input = ctxt->input;
682 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000683 input = ctxt->inputTab[ctxt->inputNr - 2];
684 }
Daniel Veillardf1edb102009-08-10 14:43:18 +0200685
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000686
687 xmlHTMLPrintFileInfo(input);
Daniel Veillardf1edb102009-08-10 14:43:18 +0200688
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000689 xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000690 va_start(args, msg);
Daniel Veillardf1edb102009-08-10 14:43:18 +0200691 len = strlen(buffer);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000692 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000693 va_end(args);
694 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000695 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000696
697 xmlHTMLPrintFileContext(input);
698 xmlHTMLEncodeSend();
699}
700
701/**
702 * xmlHTMLValidityError:
703 * @ctx: an XML parser context
704 * @msg: the message to display/transmit
705 * @...: extra parameters for the message display
Daniel Veillardf1edb102009-08-10 14:43:18 +0200706 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000707 * Display and format an validity error messages, gives file,
708 * line, position and extra parameters.
709 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000710static void XMLCDECL
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000711xmlHTMLValidityError(void *ctx, const char *msg, ...)
712{
713 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
714 xmlParserInputPtr input;
715 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000716 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000717
718 buffer[0] = 0;
719 input = ctxt->input;
720 if ((input->filename == NULL) && (ctxt->inputNr > 1))
721 input = ctxt->inputTab[ctxt->inputNr - 2];
Daniel Veillardf1edb102009-08-10 14:43:18 +0200722
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000723 xmlHTMLPrintFileInfo(input);
724
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000725 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000726 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000727 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000728 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000729 va_end(args);
730 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000731 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000732
733 xmlHTMLPrintFileContext(input);
734 xmlHTMLEncodeSend();
Daniel Veillard9fcb4912005-03-16 12:57:31 +0000735 progresult = XMLLINT_ERR_VALID;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000736}
737
738/**
739 * xmlHTMLValidityWarning:
740 * @ctx: an XML parser context
741 * @msg: the message to display/transmit
742 * @...: extra parameters for the message display
Daniel Veillardf1edb102009-08-10 14:43:18 +0200743 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000744 * Display and format a validity warning messages, gives file, line,
745 * position and extra parameters.
746 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000747static void XMLCDECL
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000748xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
749{
750 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
751 xmlParserInputPtr input;
752 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000753 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000754
755 buffer[0] = 0;
756 input = ctxt->input;
757 if ((input->filename == NULL) && (ctxt->inputNr > 1))
758 input = ctxt->inputTab[ctxt->inputNr - 2];
759
760 xmlHTMLPrintFileInfo(input);
Daniel Veillardf1edb102009-08-10 14:43:18 +0200761
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000762 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000763 va_start(args, msg);
Daniel Veillardf1edb102009-08-10 14:43:18 +0200764 len = strlen(buffer);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000765 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000766 va_end(args);
767 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000768 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000769
770 xmlHTMLPrintFileContext(input);
771 xmlHTMLEncodeSend();
772}
773
774/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +0200775 * *
776 * Shell Interface *
777 * *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000778 ************************************************************************/
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000779#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000780#ifdef LIBXML_XPATH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000781/**
782 * xmlShellReadline:
783 * @prompt: the prompt value
784 *
785 * Read a string
Daniel Veillardf1edb102009-08-10 14:43:18 +0200786 *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000787 * Returns a pointer to it or NULL on EOF the caller is expected to
788 * free the returned string.
789 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000790static char *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000791xmlShellReadline(char *prompt) {
792#ifdef HAVE_LIBREADLINE
793 char *line_read;
794
795 /* Get a line from the user. */
796 line_read = readline (prompt);
797
798 /* If the line has any text in it, save it on the history. */
799 if (line_read && *line_read)
800 add_history (line_read);
801
802 return (line_read);
803#else
804 char line_read[501];
Daniel Veillard29e43992001-12-13 22:21:58 +0000805 char *ret;
806 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000807
808 if (prompt != NULL)
809 fprintf(stdout, "%s", prompt);
810 if (!fgets(line_read, 500, stdin))
811 return(NULL);
812 line_read[500] = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000813 len = strlen(line_read);
814 ret = (char *) malloc(len + 1);
815 if (ret != NULL) {
816 memcpy (ret, line_read, len + 1);
817 }
818 return(ret);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000819#endif
820}
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000821#endif /* LIBXML_XPATH_ENABLED */
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000822#endif /* LIBXML_DEBUG_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000823
824/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +0200825 * *
826 * I/O Interfaces *
827 * *
Daniel Veillard5e873c42000-04-12 13:27:38 +0000828 ************************************************************************/
829
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000830static int myRead(FILE *f, char * buf, int len) {
831 return(fread(buf, 1, len, f));
Daniel Veillard5e873c42000-04-12 13:27:38 +0000832}
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000833static void myClose(FILE *f) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000834 if (f != stdin) {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000835 fclose(f);
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000836 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000837}
838
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000839/************************************************************************
840 * *
Daniel Veillardf1edb102009-08-10 14:43:18 +0200841 * SAX based tests *
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000842 * *
843 ************************************************************************/
844
845/*
846 * empty SAX block
847 */
Daniel Veillard24505b02005-07-28 23:49:35 +0000848static xmlSAXHandler emptySAXHandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000849 NULL, /* internalSubset */
850 NULL, /* isStandalone */
851 NULL, /* hasInternalSubset */
852 NULL, /* hasExternalSubset */
853 NULL, /* resolveEntity */
854 NULL, /* getEntity */
855 NULL, /* entityDecl */
856 NULL, /* notationDecl */
857 NULL, /* attributeDecl */
858 NULL, /* elementDecl */
859 NULL, /* unparsedEntityDecl */
860 NULL, /* setDocumentLocator */
861 NULL, /* startDocument */
862 NULL, /* endDocument */
863 NULL, /* startElement */
864 NULL, /* endElement */
865 NULL, /* reference */
866 NULL, /* characters */
867 NULL, /* ignorableWhitespace */
868 NULL, /* processingInstruction */
869 NULL, /* comment */
870 NULL, /* xmlParserWarning */
871 NULL, /* xmlParserError */
872 NULL, /* xmlParserError */
873 NULL, /* getParameterEntity */
874 NULL, /* cdataBlock; */
875 NULL, /* externalSubset; */
Daniel Veillard971771e2005-07-09 17:32:57 +0000876 XML_SAX2_MAGIC,
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000877 NULL,
878 NULL, /* startElementNs */
879 NULL, /* endElementNs */
880 NULL /* xmlStructuredErrorFunc */
881};
882
Daniel Veillard24505b02005-07-28 23:49:35 +0000883static xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000884extern xmlSAXHandlerPtr debugSAXHandler;
885static int callbacks;
886
887/**
888 * isStandaloneDebug:
889 * @ctxt: An XML parser context
890 *
891 * Is this document tagged standalone ?
892 *
893 * Returns 1 if true
894 */
895static int
896isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
897{
898 callbacks++;
899 if (noout)
900 return(0);
901 fprintf(stdout, "SAX.isStandalone()\n");
902 return(0);
903}
904
905/**
906 * hasInternalSubsetDebug:
907 * @ctxt: An XML parser context
908 *
909 * Does this document has an internal subset
910 *
911 * Returns 1 if true
912 */
913static int
914hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
915{
916 callbacks++;
917 if (noout)
918 return(0);
919 fprintf(stdout, "SAX.hasInternalSubset()\n");
920 return(0);
921}
922
923/**
924 * hasExternalSubsetDebug:
925 * @ctxt: An XML parser context
926 *
927 * Does this document has an external subset
928 *
929 * Returns 1 if true
930 */
931static int
932hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
933{
934 callbacks++;
935 if (noout)
936 return(0);
937 fprintf(stdout, "SAX.hasExternalSubset()\n");
938 return(0);
939}
940
941/**
942 * internalSubsetDebug:
943 * @ctxt: An XML parser context
944 *
945 * Does this document has an internal subset
946 */
947static void
948internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
949 const xmlChar *ExternalID, const xmlChar *SystemID)
950{
951 callbacks++;
952 if (noout)
953 return;
954 fprintf(stdout, "SAX.internalSubset(%s,", name);
955 if (ExternalID == NULL)
956 fprintf(stdout, " ,");
957 else
958 fprintf(stdout, " %s,", ExternalID);
959 if (SystemID == NULL)
960 fprintf(stdout, " )\n");
961 else
962 fprintf(stdout, " %s)\n", SystemID);
963}
964
965/**
966 * externalSubsetDebug:
967 * @ctxt: An XML parser context
968 *
969 * Does this document has an external subset
970 */
971static void
972externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
973 const xmlChar *ExternalID, const xmlChar *SystemID)
974{
975 callbacks++;
976 if (noout)
977 return;
978 fprintf(stdout, "SAX.externalSubset(%s,", name);
979 if (ExternalID == NULL)
980 fprintf(stdout, " ,");
981 else
982 fprintf(stdout, " %s,", ExternalID);
983 if (SystemID == NULL)
984 fprintf(stdout, " )\n");
985 else
986 fprintf(stdout, " %s)\n", SystemID);
987}
988
989/**
990 * resolveEntityDebug:
991 * @ctxt: An XML parser context
992 * @publicId: The public ID of the entity
993 * @systemId: The system ID of the entity
994 *
995 * Special entity resolver, better left to the parser, it has
996 * more context than the application layer.
997 * The default behaviour is to NOT resolve the entities, in that case
998 * the ENTITY_REF nodes are built in the structure (and the parameter
999 * values).
1000 *
1001 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
1002 */
1003static xmlParserInputPtr
1004resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
1005{
1006 callbacks++;
1007 if (noout)
1008 return(NULL);
1009 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1010
Daniel Veillardf1edb102009-08-10 14:43:18 +02001011
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001012 fprintf(stdout, "SAX.resolveEntity(");
1013 if (publicId != NULL)
1014 fprintf(stdout, "%s", (char *)publicId);
1015 else
1016 fprintf(stdout, " ");
1017 if (systemId != NULL)
1018 fprintf(stdout, ", %s)\n", (char *)systemId);
1019 else
1020 fprintf(stdout, ", )\n");
1021 return(NULL);
1022}
1023
1024/**
1025 * getEntityDebug:
1026 * @ctxt: An XML parser context
1027 * @name: The entity name
1028 *
1029 * Get an entity by name
1030 *
1031 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
1032 */
1033static xmlEntityPtr
1034getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1035{
1036 callbacks++;
1037 if (noout)
1038 return(NULL);
1039 fprintf(stdout, "SAX.getEntity(%s)\n", name);
1040 return(NULL);
1041}
1042
1043/**
1044 * getParameterEntityDebug:
1045 * @ctxt: An XML parser context
1046 * @name: The entity name
1047 *
1048 * Get a parameter entity by name
1049 *
1050 * Returns the xmlParserInputPtr
1051 */
1052static xmlEntityPtr
1053getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1054{
1055 callbacks++;
1056 if (noout)
1057 return(NULL);
1058 fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
1059 return(NULL);
1060}
1061
1062
1063/**
1064 * entityDeclDebug:
1065 * @ctxt: An XML parser context
Daniel Veillardf1edb102009-08-10 14:43:18 +02001066 * @name: the entity name
1067 * @type: the entity type
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001068 * @publicId: The public ID of the entity
1069 * @systemId: The system ID of the entity
1070 * @content: the entity value (without processing).
1071 *
1072 * An entity definition has been parsed
1073 */
1074static void
1075entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
1076 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
1077{
1078const xmlChar *nullstr = BAD_CAST "(null)";
1079 /* not all libraries handle printing null pointers nicely */
1080 if (publicId == NULL)
1081 publicId = nullstr;
1082 if (systemId == NULL)
1083 systemId = nullstr;
1084 if (content == NULL)
1085 content = (xmlChar *)nullstr;
1086 callbacks++;
1087 if (noout)
1088 return;
1089 fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
1090 name, type, publicId, systemId, content);
1091}
1092
1093/**
1094 * attributeDeclDebug:
1095 * @ctxt: An XML parser context
Daniel Veillardf1edb102009-08-10 14:43:18 +02001096 * @name: the attribute name
1097 * @type: the attribute type
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001098 *
1099 * An attribute definition has been parsed
1100 */
1101static void
1102attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar * elem,
1103 const xmlChar * name, int type, int def,
1104 const xmlChar * defaultValue, xmlEnumerationPtr tree)
1105{
1106 callbacks++;
1107 if (noout)
1108 return;
1109 if (defaultValue == NULL)
1110 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
1111 elem, name, type, def);
1112 else
1113 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
1114 elem, name, type, def, defaultValue);
1115 xmlFreeEnumeration(tree);
1116}
1117
1118/**
1119 * elementDeclDebug:
1120 * @ctxt: An XML parser context
Daniel Veillardf1edb102009-08-10 14:43:18 +02001121 * @name: the element name
1122 * @type: the element type
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001123 * @content: the element value (without processing).
1124 *
1125 * An element definition has been parsed
1126 */
1127static void
1128elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
1129 xmlElementContentPtr content ATTRIBUTE_UNUSED)
1130{
1131 callbacks++;
1132 if (noout)
1133 return;
1134 fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
1135 name, type);
1136}
1137
1138/**
1139 * notationDeclDebug:
1140 * @ctxt: An XML parser context
1141 * @name: The name of the notation
1142 * @publicId: The public ID of the entity
1143 * @systemId: The system ID of the entity
1144 *
1145 * What to do when a notation declaration has been parsed.
1146 */
1147static void
1148notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
1149 const xmlChar *publicId, const xmlChar *systemId)
1150{
1151 callbacks++;
1152 if (noout)
1153 return;
1154 fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
1155 (char *) name, (char *) publicId, (char *) systemId);
1156}
1157
1158/**
1159 * unparsedEntityDeclDebug:
1160 * @ctxt: An XML parser context
1161 * @name: The name of the entity
1162 * @publicId: The public ID of the entity
1163 * @systemId: The system ID of the entity
1164 * @notationName: the name of the notation
1165 *
1166 * What to do when an unparsed entity declaration is parsed
1167 */
1168static void
1169unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
1170 const xmlChar *publicId, const xmlChar *systemId,
1171 const xmlChar *notationName)
1172{
1173const xmlChar *nullstr = BAD_CAST "(null)";
1174
1175 if (publicId == NULL)
1176 publicId = nullstr;
1177 if (systemId == NULL)
1178 systemId = nullstr;
1179 if (notationName == NULL)
1180 notationName = nullstr;
1181 callbacks++;
1182 if (noout)
1183 return;
1184 fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
1185 (char *) name, (char *) publicId, (char *) systemId,
1186 (char *) notationName);
1187}
1188
1189/**
1190 * setDocumentLocatorDebug:
1191 * @ctxt: An XML parser context
1192 * @loc: A SAX Locator
1193 *
1194 * Receive the document locator at startup, actually xmlDefaultSAXLocator
1195 * Everything is available on the context, so this is useless in our case.
1196 */
1197static void
1198setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
1199{
1200 callbacks++;
1201 if (noout)
1202 return;
1203 fprintf(stdout, "SAX.setDocumentLocator()\n");
1204}
1205
1206/**
1207 * startDocumentDebug:
1208 * @ctxt: An XML parser context
1209 *
1210 * called when the document start being processed.
1211 */
1212static void
1213startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
1214{
1215 callbacks++;
1216 if (noout)
1217 return;
1218 fprintf(stdout, "SAX.startDocument()\n");
1219}
1220
1221/**
1222 * endDocumentDebug:
1223 * @ctxt: An XML parser context
1224 *
1225 * called when the document end has been detected.
1226 */
1227static void
1228endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
1229{
1230 callbacks++;
1231 if (noout)
1232 return;
1233 fprintf(stdout, "SAX.endDocument()\n");
1234}
1235
1236/**
1237 * startElementDebug:
1238 * @ctxt: An XML parser context
1239 * @name: The element name
1240 *
1241 * called when an opening tag has been processed.
1242 */
1243static void
1244startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
1245{
1246 int i;
1247
1248 callbacks++;
1249 if (noout)
1250 return;
1251 fprintf(stdout, "SAX.startElement(%s", (char *) name);
1252 if (atts != NULL) {
1253 for (i = 0;(atts[i] != NULL);i++) {
1254 fprintf(stdout, ", %s='", atts[i++]);
1255 if (atts[i] != NULL)
1256 fprintf(stdout, "%s'", atts[i]);
1257 }
1258 }
1259 fprintf(stdout, ")\n");
1260}
1261
1262/**
1263 * endElementDebug:
1264 * @ctxt: An XML parser context
1265 * @name: The element name
1266 *
1267 * called when the end of an element has been detected.
1268 */
1269static void
1270endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1271{
1272 callbacks++;
1273 if (noout)
1274 return;
1275 fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
1276}
1277
1278/**
1279 * charactersDebug:
1280 * @ctxt: An XML parser context
1281 * @ch: a xmlChar string
1282 * @len: the number of xmlChar
1283 *
1284 * receiving some chars from the parser.
1285 * Question: how much at a time ???
1286 */
1287static void
1288charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
1289{
1290 char out[40];
1291 int i;
1292
1293 callbacks++;
1294 if (noout)
1295 return;
1296 for (i = 0;(i<len) && (i < 30);i++)
1297 out[i] = ch[i];
1298 out[i] = 0;
1299
1300 fprintf(stdout, "SAX.characters(%s, %d)\n", out, len);
1301}
1302
1303/**
1304 * referenceDebug:
1305 * @ctxt: An XML parser context
1306 * @name: The entity name
1307 *
Daniel Veillardf1edb102009-08-10 14:43:18 +02001308 * called when an entity reference is detected.
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001309 */
1310static void
1311referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1312{
1313 callbacks++;
1314 if (noout)
1315 return;
1316 fprintf(stdout, "SAX.reference(%s)\n", name);
1317}
1318
1319/**
1320 * ignorableWhitespaceDebug:
1321 * @ctxt: An XML parser context
1322 * @ch: a xmlChar string
1323 * @start: the first char in the string
1324 * @len: the number of xmlChar
1325 *
1326 * receiving some ignorable whitespaces from the parser.
1327 * Question: how much at a time ???
1328 */
1329static void
1330ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
1331{
1332 char out[40];
1333 int i;
1334
1335 callbacks++;
1336 if (noout)
1337 return;
1338 for (i = 0;(i<len) && (i < 30);i++)
1339 out[i] = ch[i];
1340 out[i] = 0;
1341 fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", out, len);
1342}
1343
1344/**
1345 * processingInstructionDebug:
1346 * @ctxt: An XML parser context
1347 * @target: the target name
1348 * @data: the PI data's
1349 * @len: the number of xmlChar
1350 *
1351 * A processing instruction has been parsed.
1352 */
1353static void
1354processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
1355 const xmlChar *data)
1356{
1357 callbacks++;
1358 if (noout)
1359 return;
1360 if (data != NULL)
1361 fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
1362 (char *) target, (char *) data);
1363 else
1364 fprintf(stdout, "SAX.processingInstruction(%s, NULL)\n",
1365 (char *) target);
1366}
1367
1368/**
1369 * cdataBlockDebug:
1370 * @ctx: the user data (XML parser context)
1371 * @value: The pcdata content
1372 * @len: the block length
1373 *
1374 * called when a pcdata block has been parsed
1375 */
1376static void
1377cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
1378{
1379 callbacks++;
1380 if (noout)
1381 return;
1382 fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
1383 (char *) value, len);
1384}
1385
1386/**
1387 * commentDebug:
1388 * @ctxt: An XML parser context
1389 * @value: the comment content
1390 *
1391 * A comment has been parsed.
1392 */
1393static void
1394commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
1395{
1396 callbacks++;
1397 if (noout)
1398 return;
1399 fprintf(stdout, "SAX.comment(%s)\n", value);
1400}
1401
1402/**
1403 * warningDebug:
1404 * @ctxt: An XML parser context
1405 * @msg: the message to display/transmit
1406 * @...: extra parameters for the message display
1407 *
1408 * Display and format a warning messages, gives file, line, position and
1409 * extra parameters.
1410 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001411static void XMLCDECL
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001412warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1413{
1414 va_list args;
1415
1416 callbacks++;
1417 if (noout)
1418 return;
1419 va_start(args, msg);
1420 fprintf(stdout, "SAX.warning: ");
1421 vfprintf(stdout, msg, args);
1422 va_end(args);
1423}
1424
1425/**
1426 * errorDebug:
1427 * @ctxt: An XML parser context
1428 * @msg: the message to display/transmit
1429 * @...: extra parameters for the message display
1430 *
1431 * Display and format a error messages, gives file, line, position and
1432 * extra parameters.
1433 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001434static void XMLCDECL
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001435errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1436{
1437 va_list args;
1438
1439 callbacks++;
1440 if (noout)
1441 return;
1442 va_start(args, msg);
1443 fprintf(stdout, "SAX.error: ");
1444 vfprintf(stdout, msg, args);
1445 va_end(args);
1446}
1447
1448/**
1449 * fatalErrorDebug:
1450 * @ctxt: An XML parser context
1451 * @msg: the message to display/transmit
1452 * @...: extra parameters for the message display
1453 *
1454 * Display and format a fatalError messages, gives file, line, position and
1455 * extra parameters.
1456 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001457static void XMLCDECL
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001458fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1459{
1460 va_list args;
1461
1462 callbacks++;
1463 if (noout)
1464 return;
1465 va_start(args, msg);
1466 fprintf(stdout, "SAX.fatalError: ");
1467 vfprintf(stdout, msg, args);
1468 va_end(args);
1469}
1470
Daniel Veillard24505b02005-07-28 23:49:35 +00001471static xmlSAXHandler debugSAXHandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001472 internalSubsetDebug,
1473 isStandaloneDebug,
1474 hasInternalSubsetDebug,
1475 hasExternalSubsetDebug,
1476 resolveEntityDebug,
1477 getEntityDebug,
1478 entityDeclDebug,
1479 notationDeclDebug,
1480 attributeDeclDebug,
1481 elementDeclDebug,
1482 unparsedEntityDeclDebug,
1483 setDocumentLocatorDebug,
1484 startDocumentDebug,
1485 endDocumentDebug,
1486 startElementDebug,
1487 endElementDebug,
1488 referenceDebug,
1489 charactersDebug,
1490 ignorableWhitespaceDebug,
1491 processingInstructionDebug,
1492 commentDebug,
1493 warningDebug,
1494 errorDebug,
1495 fatalErrorDebug,
1496 getParameterEntityDebug,
1497 cdataBlockDebug,
1498 externalSubsetDebug,
1499 1,
1500 NULL,
1501 NULL,
1502 NULL,
1503 NULL
1504};
1505
1506xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
1507
1508/*
1509 * SAX2 specific callbacks
1510 */
1511/**
1512 * startElementNsDebug:
1513 * @ctxt: An XML parser context
1514 * @name: The element name
1515 *
1516 * called when an opening tag has been processed.
1517 */
1518static void
1519startElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
1520 const xmlChar *localname,
1521 const xmlChar *prefix,
1522 const xmlChar *URI,
1523 int nb_namespaces,
1524 const xmlChar **namespaces,
1525 int nb_attributes,
1526 int nb_defaulted,
1527 const xmlChar **attributes)
1528{
1529 int i;
1530
1531 callbacks++;
1532 if (noout)
1533 return;
1534 fprintf(stdout, "SAX.startElementNs(%s", (char *) localname);
1535 if (prefix == NULL)
1536 fprintf(stdout, ", NULL");
1537 else
1538 fprintf(stdout, ", %s", (char *) prefix);
1539 if (URI == NULL)
1540 fprintf(stdout, ", NULL");
1541 else
1542 fprintf(stdout, ", '%s'", (char *) URI);
1543 fprintf(stdout, ", %d", nb_namespaces);
Daniel Veillardf1edb102009-08-10 14:43:18 +02001544
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001545 if (namespaces != NULL) {
1546 for (i = 0;i < nb_namespaces * 2;i++) {
1547 fprintf(stdout, ", xmlns");
1548 if (namespaces[i] != NULL)
1549 fprintf(stdout, ":%s", namespaces[i]);
1550 i++;
1551 fprintf(stdout, "='%s'", namespaces[i]);
1552 }
1553 }
1554 fprintf(stdout, ", %d, %d", nb_attributes, nb_defaulted);
1555 if (attributes != NULL) {
1556 for (i = 0;i < nb_attributes * 5;i += 5) {
1557 if (attributes[i + 1] != NULL)
1558 fprintf(stdout, ", %s:%s='", attributes[i + 1], attributes[i]);
1559 else
1560 fprintf(stdout, ", %s='", attributes[i]);
1561 fprintf(stdout, "%.4s...', %d", attributes[i + 3],
1562 (int)(attributes[i + 4] - attributes[i + 3]));
1563 }
1564 }
1565 fprintf(stdout, ")\n");
1566}
1567
1568/**
1569 * endElementDebug:
1570 * @ctxt: An XML parser context
1571 * @name: The element name
1572 *
1573 * called when the end of an element has been detected.
1574 */
1575static void
1576endElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
1577 const xmlChar *localname,
1578 const xmlChar *prefix,
1579 const xmlChar *URI)
1580{
1581 callbacks++;
1582 if (noout)
1583 return;
1584 fprintf(stdout, "SAX.endElementNs(%s", (char *) localname);
1585 if (prefix == NULL)
1586 fprintf(stdout, ", NULL");
1587 else
1588 fprintf(stdout, ", %s", (char *) prefix);
1589 if (URI == NULL)
1590 fprintf(stdout, ", NULL)\n");
1591 else
1592 fprintf(stdout, ", '%s')\n", (char *) URI);
1593}
1594
Daniel Veillard24505b02005-07-28 23:49:35 +00001595static xmlSAXHandler debugSAX2HandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001596 internalSubsetDebug,
1597 isStandaloneDebug,
1598 hasInternalSubsetDebug,
1599 hasExternalSubsetDebug,
1600 resolveEntityDebug,
1601 getEntityDebug,
1602 entityDeclDebug,
1603 notationDeclDebug,
1604 attributeDeclDebug,
1605 elementDeclDebug,
1606 unparsedEntityDeclDebug,
1607 setDocumentLocatorDebug,
1608 startDocumentDebug,
1609 endDocumentDebug,
1610 NULL,
1611 NULL,
1612 referenceDebug,
1613 charactersDebug,
1614 ignorableWhitespaceDebug,
1615 processingInstructionDebug,
1616 commentDebug,
1617 warningDebug,
1618 errorDebug,
1619 fatalErrorDebug,
1620 getParameterEntityDebug,
1621 cdataBlockDebug,
1622 externalSubsetDebug,
1623 XML_SAX2_MAGIC,
1624 NULL,
1625 startElementNsDebug,
1626 endElementNsDebug,
1627 NULL
1628};
1629
Daniel Veillard24505b02005-07-28 23:49:35 +00001630static xmlSAXHandlerPtr debugSAX2Handler = &debugSAX2HandlerStruct;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001631
1632static void
1633testSAX(const char *filename) {
1634 xmlSAXHandlerPtr handler;
1635 const char *user_data = "user_data"; /* mostly for debugging */
1636 xmlParserInputBufferPtr buf = NULL;
1637 xmlParserInputPtr inputStream;
1638 xmlParserCtxtPtr ctxt = NULL;
1639 xmlSAXHandlerPtr old_sax = NULL;
1640
1641 callbacks = 0;
1642
1643 if (noout) {
1644 handler = emptySAXHandler;
Daniel Veillard78dfc9f2005-07-10 22:30:30 +00001645#ifdef LIBXML_SAX1_ENABLED
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001646 } else if (sax1) {
1647 handler = debugSAXHandler;
Daniel Veillard78dfc9f2005-07-10 22:30:30 +00001648#endif
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001649 } else {
1650 handler = debugSAX2Handler;
1651 }
1652
1653 /*
1654 * it's not the simplest code but the most generic in term of I/O
1655 */
1656 buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
1657 if (buf == NULL) {
1658 goto error;
1659 }
1660
1661#ifdef LIBXML_SCHEMAS_ENABLED
1662 if (wxschemas != NULL) {
1663 int ret;
1664 xmlSchemaValidCtxtPtr vctxt;
1665
1666 vctxt = xmlSchemaNewValidCtxt(wxschemas);
1667 xmlSchemaSetValidErrors(vctxt,
1668 (xmlSchemaValidityErrorFunc) fprintf,
1669 (xmlSchemaValidityWarningFunc) fprintf,
1670 stderr);
1671
Daniel Veillard971771e2005-07-09 17:32:57 +00001672 ret = xmlSchemaValidateStream(vctxt, buf, 0, handler,
1673 (void *)user_data);
1674 if (repeat == 0) {
1675 if (ret == 0) {
1676 fprintf(stderr, "%s validates\n", filename);
1677 } else if (ret > 0) {
1678 fprintf(stderr, "%s fails to validate\n", filename);
1679 progresult = XMLLINT_ERR_VALID;
1680 } else {
1681 fprintf(stderr, "%s validation generated an internal error\n",
1682 filename);
1683 progresult = XMLLINT_ERR_VALID;
1684 }
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001685 }
1686 xmlSchemaFreeValidCtxt(vctxt);
1687 } else
1688#endif
1689 {
1690 /*
1691 * Create the parser context amd hook the input
1692 */
1693 ctxt = xmlNewParserCtxt();
1694 if (ctxt == NULL) {
1695 xmlFreeParserInputBuffer(buf);
1696 goto error;
1697 }
1698 old_sax = ctxt->sax;
1699 ctxt->sax = handler;
1700 ctxt->userData = (void *) user_data;
1701 inputStream = xmlNewIOInputStream(ctxt, buf, XML_CHAR_ENCODING_NONE);
1702 if (inputStream == NULL) {
1703 xmlFreeParserInputBuffer(buf);
1704 goto error;
1705 }
1706 inputPush(ctxt, inputStream);
Daniel Veillardf1edb102009-08-10 14:43:18 +02001707
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001708 /* do the parsing */
1709 xmlParseDocument(ctxt);
1710
1711 if (ctxt->myDoc != NULL) {
1712 fprintf(stderr, "SAX generated a doc !\n");
1713 xmlFreeDoc(ctxt->myDoc);
1714 ctxt->myDoc = NULL;
1715 }
1716 }
1717
1718error:
1719 if (ctxt != NULL) {
1720 ctxt->sax = old_sax;
1721 xmlFreeParserCtxt(ctxt);
1722 }
1723}
1724
Daniel Veillard5e873c42000-04-12 13:27:38 +00001725/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +02001726 * *
1727 * Stream Test processing *
1728 * *
Daniel Veillard7704fb12003-01-03 16:19:51 +00001729 ************************************************************************/
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001730#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00001731static void processNode(xmlTextReaderPtr reader) {
Daniel Veillard198c1bf2003-10-20 17:07:41 +00001732 const xmlChar *name, *value;
Daniel Veillard16ef8002005-01-31 00:27:50 +00001733 int type, empty;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001734
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001735 type = xmlTextReaderNodeType(reader);
Daniel Veillard16ef8002005-01-31 00:27:50 +00001736 empty = xmlTextReaderIsEmptyElement(reader);
Daniel Veillard99737f52003-03-22 14:55:50 +00001737
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001738 if (debug) {
1739 name = xmlTextReaderConstName(reader);
1740 if (name == NULL)
1741 name = BAD_CAST "--";
Daniel Veillard7704fb12003-01-03 16:19:51 +00001742
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001743 value = xmlTextReaderConstValue(reader);
1744
Daniel Veillardf1edb102009-08-10 14:43:18 +02001745
1746 printf("%d %d %s %d %d",
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001747 xmlTextReaderDepth(reader),
1748 type,
1749 name,
Daniel Veillard16ef8002005-01-31 00:27:50 +00001750 empty,
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001751 xmlTextReaderHasValue(reader));
1752 if (value == NULL)
1753 printf("\n");
1754 else {
1755 printf(" %s\n", value);
1756 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001757 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001758#ifdef LIBXML_PATTERN_ENABLED
1759 if (patternc) {
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001760 xmlChar *path = NULL;
1761 int match = -1;
Daniel Veillardf1edb102009-08-10 14:43:18 +02001762
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001763 if (type == XML_READER_TYPE_ELEMENT) {
1764 /* do the check only on element start */
1765 match = xmlPatternMatch(patternc, xmlTextReaderCurrentNode(reader));
1766
1767 if (match) {
Daniel Veillardf1edb102009-08-10 14:43:18 +02001768#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001769 path = xmlGetNodePath(xmlTextReaderCurrentNode(reader));
1770 printf("Node %s matches pattern %s\n", path, pattern);
Daniel Veillardf1edb102009-08-10 14:43:18 +02001771#else
1772 printf("Node %s matches pattern %s\n",
1773 xmlTextReaderConstName(reader), pattern);
1774#endif
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001775 }
1776 }
1777 if (patstream != NULL) {
1778 int ret;
1779
1780 if (type == XML_READER_TYPE_ELEMENT) {
1781 ret = xmlStreamPush(patstream,
1782 xmlTextReaderConstLocalName(reader),
1783 xmlTextReaderConstNamespaceUri(reader));
1784 if (ret < 0) {
1785 fprintf(stderr, "xmlStreamPush() failure\n");
1786 xmlFreeStreamCtxt(patstream);
1787 patstream = NULL;
1788 } else if (ret != match) {
Daniel Veillardf1edb102009-08-10 14:43:18 +02001789#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001790 if (path == NULL) {
1791 path = xmlGetNodePath(
1792 xmlTextReaderCurrentNode(reader));
1793 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02001794#endif
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001795 fprintf(stderr,
1796 "xmlPatternMatch and xmlStreamPush disagree\n");
Daniel Veillardf1edb102009-08-10 14:43:18 +02001797 if (path != NULL)
1798 fprintf(stderr, " pattern %s node %s\n",
1799 pattern, path);
1800 else
1801 fprintf(stderr, " pattern %s node %s\n",
1802 pattern, xmlTextReaderConstName(reader));
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001803 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001804
Daniel Veillardf1edb102009-08-10 14:43:18 +02001805 }
Daniel Veillard16ef8002005-01-31 00:27:50 +00001806 if ((type == XML_READER_TYPE_END_ELEMENT) ||
1807 ((type == XML_READER_TYPE_ELEMENT) && (empty))) {
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001808 ret = xmlStreamPop(patstream);
1809 if (ret < 0) {
1810 fprintf(stderr, "xmlStreamPop() failure\n");
1811 xmlFreeStreamCtxt(patstream);
1812 patstream = NULL;
1813 }
1814 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001815 }
Daniel Veillardf9d16912005-01-30 22:36:30 +00001816 if (path != NULL)
1817 xmlFree(path);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001818 }
1819#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001820}
1821
1822static void streamFile(char *filename) {
1823 xmlTextReaderPtr reader;
1824 int ret;
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001825#ifdef HAVE_SYS_MMAN_H
1826 int fd = -1;
1827 struct stat info;
1828 const char *base = NULL;
1829 xmlParserInputBufferPtr input = NULL;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001830
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001831 if (memory) {
Daniel Veillardf1edb102009-08-10 14:43:18 +02001832 if (stat(filename, &info) < 0)
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001833 return;
1834 if ((fd = open(filename, O_RDONLY)) < 0)
1835 return;
1836 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
1837 if (base == (void *) MAP_FAILED)
1838 return;
1839
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001840 reader = xmlReaderForMemory(base, info.st_size, filename,
1841 NULL, options);
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001842 } else
1843#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001844 reader = xmlReaderForFile(filename, NULL, options);
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001845#ifdef LIBXML_PATTERN_ENABLED
Daniel Veillardd4301ab2005-02-03 22:24:10 +00001846 if (pattern != NULL) {
1847 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
1848 if (patternc == NULL) {
1849 xmlGenericError(xmlGenericErrorContext,
1850 "Pattern %s failed to compile\n", pattern);
1851 progresult = XMLLINT_ERR_SCHEMAPAT;
1852 pattern = NULL;
1853 }
1854 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001855 if (patternc != NULL) {
1856 patstream = xmlPatternGetStreamCtxt(patternc);
1857 if (patstream != NULL) {
1858 ret = xmlStreamPush(patstream, NULL, NULL);
1859 if (ret < 0) {
1860 fprintf(stderr, "xmlStreamPush() failure\n");
1861 xmlFreeStreamCtxt(patstream);
1862 patstream = NULL;
1863 }
1864 }
1865 }
1866#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001867
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001868
Daniel Veillard7704fb12003-01-03 16:19:51 +00001869 if (reader != NULL) {
Daniel Veillard4432df22003-09-28 18:58:27 +00001870#ifdef LIBXML_VALID_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00001871 if (valid)
1872 xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
Daniel Veillardce192eb2003-04-16 15:58:05 +00001873 else
Daniel Veillard4432df22003-09-28 18:58:27 +00001874#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardce192eb2003-04-16 15:58:05 +00001875 xmlTextReaderSetParserProp(reader, XML_PARSER_LOADDTD, 1);
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001876#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +00001877 if (relaxng != NULL) {
Daniel Veillard81514ba2003-09-16 23:17:26 +00001878 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001879 startTimer();
1880 }
1881 ret = xmlTextReaderRelaxNGValidate(reader, relaxng);
1882 if (ret < 0) {
1883 xmlGenericError(xmlGenericErrorContext,
1884 "Relax-NG schema %s failed to compile\n", relaxng);
William M. Brack8304d872004-06-08 13:29:32 +00001885 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillardce192eb2003-04-16 15:58:05 +00001886 relaxng = NULL;
1887 }
Daniel Veillard81514ba2003-09-16 23:17:26 +00001888 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001889 endTimer("Compiling the schemas");
1890 }
1891 }
Daniel Veillardf10ae122005-07-10 19:03:16 +00001892 if (schema != NULL) {
1893 if ((timing) && (!repeat)) {
1894 startTimer();
1895 }
1896 ret = xmlTextReaderSchemaValidate(reader, schema);
1897 if (ret < 0) {
1898 xmlGenericError(xmlGenericErrorContext,
1899 "XSD schema %s failed to compile\n", schema);
1900 progresult = XMLLINT_ERR_SCHEMACOMP;
1901 schema = NULL;
1902 }
1903 if ((timing) && (!repeat)) {
1904 endTimer("Compiling the schemas");
1905 }
1906 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001907#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001908
1909 /*
1910 * Process all nodes in sequence
1911 */
Daniel Veillard81514ba2003-09-16 23:17:26 +00001912 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001913 startTimer();
1914 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001915 ret = xmlTextReaderRead(reader);
1916 while (ret == 1) {
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001917 if ((debug)
1918#ifdef LIBXML_PATTERN_ENABLED
1919 || (patternc)
1920#endif
1921 )
Daniel Veillard7704fb12003-01-03 16:19:51 +00001922 processNode(reader);
1923 ret = xmlTextReaderRead(reader);
1924 }
Daniel Veillard81514ba2003-09-16 23:17:26 +00001925 if ((timing) && (!repeat)) {
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001926#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf54cd532004-02-25 11:52:31 +00001927 if (relaxng != NULL)
Daniel Veillard49138f12004-02-19 12:58:36 +00001928 endTimer("Parsing and validating");
1929 else
Daniel Veillardf54cd532004-02-25 11:52:31 +00001930#endif
Daniel Veillard4432df22003-09-28 18:58:27 +00001931#ifdef LIBXML_VALID_ENABLED
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001932 if (valid)
Daniel Veillardce192eb2003-04-16 15:58:05 +00001933 endTimer("Parsing and validating");
1934 else
Daniel Veillard4432df22003-09-28 18:58:27 +00001935#endif
Daniel Veillardf54cd532004-02-25 11:52:31 +00001936 endTimer("Parsing");
Daniel Veillardce192eb2003-04-16 15:58:05 +00001937 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001938
Daniel Veillard4432df22003-09-28 18:58:27 +00001939#ifdef LIBXML_VALID_ENABLED
Daniel Veillardf6bad792003-04-11 19:38:54 +00001940 if (valid) {
1941 if (xmlTextReaderIsValid(reader) != 1) {
1942 xmlGenericError(xmlGenericErrorContext,
1943 "Document %s does not validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001944 progresult = XMLLINT_ERR_VALID;
Daniel Veillardf6bad792003-04-11 19:38:54 +00001945 }
1946 }
Daniel Veillard4432df22003-09-28 18:58:27 +00001947#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001948#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf10ae122005-07-10 19:03:16 +00001949 if ((relaxng != NULL) || (schema != NULL)) {
Daniel Veillardf4e55762003-04-15 23:32:22 +00001950 if (xmlTextReaderIsValid(reader) != 1) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001951 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001952 progresult = XMLLINT_ERR_VALID;
Daniel Veillardf4e55762003-04-15 23:32:22 +00001953 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001954 fprintf(stderr, "%s validates\n", filename);
Daniel Veillardf4e55762003-04-15 23:32:22 +00001955 }
1956 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001957#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001958 /*
1959 * Done, cleanup and status
1960 */
1961 xmlFreeTextReader(reader);
1962 if (ret != 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001963 fprintf(stderr, "%s : failed to parse\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001964 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001965 }
1966 } else {
1967 fprintf(stderr, "Unable to open %s\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001968 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001969 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001970#ifdef LIBXML_PATTERN_ENABLED
1971 if (patstream != NULL) {
1972 xmlFreeStreamCtxt(patstream);
1973 patstream = NULL;
1974 }
1975#endif
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001976#ifdef HAVE_SYS_MMAN_H
1977 if (memory) {
1978 xmlFreeParserInputBuffer(input);
1979 munmap((char *) base, info.st_size);
1980 close(fd);
1981 }
1982#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001983}
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001984
1985static void walkDoc(xmlDocPtr doc) {
1986 xmlTextReaderPtr reader;
1987 int ret;
1988
Daniel Veillardd4301ab2005-02-03 22:24:10 +00001989#ifdef LIBXML_PATTERN_ENABLED
1990 xmlNodePtr root;
1991 const xmlChar *namespaces[22];
1992 int i;
1993 xmlNsPtr ns;
1994
1995 root = xmlDocGetRootElement(doc);
1996 for (ns = root->nsDef, i = 0;ns != NULL && i < 20;ns=ns->next) {
1997 namespaces[i++] = ns->href;
1998 namespaces[i++] = ns->prefix;
1999 }
2000 namespaces[i++] = NULL;
Daniel Veillard13cee4e2009-09-05 14:52:55 +02002001 namespaces[i] = NULL;
Daniel Veillardd4301ab2005-02-03 22:24:10 +00002002
2003 if (pattern != NULL) {
2004 patternc = xmlPatterncompile((const xmlChar *) pattern, doc->dict,
2005 0, &namespaces[0]);
2006 if (patternc == NULL) {
2007 xmlGenericError(xmlGenericErrorContext,
2008 "Pattern %s failed to compile\n", pattern);
2009 progresult = XMLLINT_ERR_SCHEMAPAT;
2010 pattern = NULL;
2011 }
2012 }
Daniel Veillard2b2e02d2005-02-05 23:20:22 +00002013 if (patternc != NULL) {
2014 patstream = xmlPatternGetStreamCtxt(patternc);
2015 if (patstream != NULL) {
2016 ret = xmlStreamPush(patstream, NULL, NULL);
2017 if (ret < 0) {
2018 fprintf(stderr, "xmlStreamPush() failure\n");
2019 xmlFreeStreamCtxt(patstream);
2020 patstream = NULL;
2021 }
2022 }
2023 }
Daniel Veillardd4301ab2005-02-03 22:24:10 +00002024#endif /* LIBXML_PATTERN_ENABLED */
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002025 reader = xmlReaderWalker(doc);
2026 if (reader != NULL) {
2027 if ((timing) && (!repeat)) {
2028 startTimer();
2029 }
2030 ret = xmlTextReaderRead(reader);
2031 while (ret == 1) {
Daniel Veillardb3de70c2003-12-02 22:32:15 +00002032 if ((debug)
2033#ifdef LIBXML_PATTERN_ENABLED
2034 || (patternc)
2035#endif
2036 )
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002037 processNode(reader);
2038 ret = xmlTextReaderRead(reader);
2039 }
2040 if ((timing) && (!repeat)) {
2041 endTimer("walking through the doc");
2042 }
2043 xmlFreeTextReader(reader);
2044 if (ret != 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002045 fprintf(stderr, "failed to walk through the doc\n");
William M. Brack8304d872004-06-08 13:29:32 +00002046 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002047 }
2048 } else {
2049 fprintf(stderr, "Failed to crate a reader from the document\n");
William M. Brack8304d872004-06-08 13:29:32 +00002050 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002051 }
Daniel Veillard2b2e02d2005-02-05 23:20:22 +00002052#ifdef LIBXML_PATTERN_ENABLED
2053 if (patstream != NULL) {
2054 xmlFreeStreamCtxt(patstream);
2055 patstream = NULL;
2056 }
2057#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002058}
Daniel Veillard81273902003-09-30 00:43:48 +00002059#endif /* LIBXML_READER_ENABLED */
Daniel Veillard7704fb12003-01-03 16:19:51 +00002060
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002061#ifdef LIBXML_XPATH_ENABLED
2062/************************************************************************
2063 * *
2064 * XPath Query *
2065 * *
2066 ************************************************************************/
2067
2068static void doXPathDump(xmlXPathObjectPtr cur) {
2069 switch(cur->type) {
2070 case XPATH_NODESET: {
2071 int i;
2072 xmlNodePtr node;
2073#ifdef LIBXML_OUTPUT_ENABLED
2074 xmlSaveCtxtPtr ctxt;
2075
Daniel Veillardbdc64d62012-03-27 14:41:37 +08002076 if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr <= 0)) {
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002077 fprintf(stderr, "XPath set is empty\n");
2078 progresult = XMLLINT_ERR_XPATH;
2079 break;
2080 }
2081 ctxt = xmlSaveToFd(1, NULL, 0);
2082 if (ctxt == NULL) {
2083 fprintf(stderr, "Out of memory for XPath\n");
2084 progresult = XMLLINT_ERR_MEM;
2085 return;
2086 }
2087 for (i = 0;i < cur->nodesetval->nodeNr;i++) {
2088 node = cur->nodesetval->nodeTab[i];
2089 xmlSaveTree(ctxt, node);
2090 }
2091 xmlSaveClose(ctxt);
2092#else
2093 printf("xpath returned %d nodes\n", cur->nodesetval->nodeNr);
2094#endif
2095 break;
2096 }
2097 case XPATH_BOOLEAN:
2098 if (cur->boolval) printf("true");
2099 else printf("false");
2100 break;
2101 case XPATH_NUMBER:
2102 switch (xmlXPathIsInf(cur->floatval)) {
2103 case 1:
2104 printf("Infinity");
2105 break;
2106 case -1:
2107 printf("-Infinity");
2108 break;
2109 default:
2110 if (xmlXPathIsNaN(cur->floatval)) {
2111 printf("NaN");
2112 } else {
2113 printf("%0g", cur->floatval);
2114 }
2115 }
2116 break;
2117 case XPATH_STRING:
2118 printf("%s", (const char *) cur->stringval);
2119 break;
2120 case XPATH_UNDEFINED:
2121 fprintf(stderr, "XPath Object is uninitialized\n");
2122 progresult = XMLLINT_ERR_XPATH;
2123 break;
2124 default:
2125 fprintf(stderr, "XPath object of unexpected type\n");
2126 progresult = XMLLINT_ERR_XPATH;
2127 break;
2128 }
2129}
2130
2131static void doXPathQuery(xmlDocPtr doc, const char *query) {
2132 xmlXPathContextPtr ctxt;
2133 xmlXPathObjectPtr res;
2134
2135 ctxt = xmlXPathNewContext(doc);
2136 if (ctxt == NULL) {
2137 fprintf(stderr, "Out of memory for XPath\n");
2138 progresult = XMLLINT_ERR_MEM;
2139 return;
2140 }
2141 ctxt->node = xmlDocGetRootElement(doc);
2142 res = xmlXPathEval(BAD_CAST query, ctxt);
2143 xmlXPathFreeContext(ctxt);
2144
2145 if (res == NULL) {
2146 fprintf(stderr, "XPath evaluation failure\n");
2147 progresult = XMLLINT_ERR_XPATH;
2148 return;
2149 }
2150 doXPathDump(res);
2151 xmlXPathFreeObject(res);
2152}
2153#endif /* LIBXML_XPATH_ENABLED */
2154
Daniel Veillard7704fb12003-01-03 16:19:51 +00002155/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +02002156 * *
2157 * Tree Test processing *
2158 * *
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002159 ************************************************************************/
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002160static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
Daniel Veillard652327a2003-09-29 18:02:38 +00002161 xmlDocPtr doc = NULL;
2162#ifdef LIBXML_TREE_ENABLED
2163 xmlDocPtr tmp;
2164#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002165
Daniel Veillard48b2f892001-02-25 16:11:03 +00002166 if ((timing) && (!repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00002167 startTimer();
Daniel Veillardf1edb102009-08-10 14:43:18 +02002168
Daniel Veillard48b2f892001-02-25 16:11:03 +00002169
Daniel Veillard652327a2003-09-29 18:02:38 +00002170#ifdef LIBXML_TREE_ENABLED
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002171 if (filename == NULL) {
2172 if (generate) {
2173 xmlNodePtr n;
2174
2175 doc = xmlNewDoc(BAD_CAST "1.0");
Daniel Veillard95ddcd32004-10-26 21:53:55 +00002176 n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002177 xmlNodeSetContent(n, BAD_CAST "abc");
2178 xmlDocSetRootElement(doc, n);
2179 }
2180 }
Daniel Veillard652327a2003-09-29 18:02:38 +00002181#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002182#ifdef LIBXML_HTML_ENABLED
Daniel Veillard73b013f2003-09-30 12:36:01 +00002183#ifdef LIBXML_PUSH_ENABLED
William M. Brack78637da2003-07-31 14:47:38 +00002184 else if ((html) && (push)) {
2185 FILE *f;
2186
William M. Brack3403add2004-06-27 02:07:51 +00002187#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2188 f = fopen(filename, "rb");
2189#else
2190 f = fopen(filename, "r");
2191#endif
William M. Brack78637da2003-07-31 14:47:38 +00002192 if (f != NULL) {
2193 int res, size = 3;
2194 char chars[4096];
2195 htmlParserCtxtPtr ctxt;
2196
2197 /* if (repeat) */
2198 size = 4096;
2199 res = fread(chars, 1, 4, f);
2200 if (res > 0) {
2201 ctxt = htmlCreatePushParserCtxt(NULL, NULL,
William M. Brack1d75c8a2003-10-27 13:48:16 +00002202 chars, res, filename, XML_CHAR_ENCODING_NONE);
William M. Brack78637da2003-07-31 14:47:38 +00002203 while ((res = fread(chars, 1, size, f)) > 0) {
2204 htmlParseChunk(ctxt, chars, res, 0);
2205 }
2206 htmlParseChunk(ctxt, chars, 0, 1);
2207 doc = ctxt->myDoc;
2208 htmlFreeParserCtxt(ctxt);
2209 }
2210 fclose(f);
2211 }
2212 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00002213#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002214#ifdef HAVE_SYS_MMAN_H
2215 else if ((html) && (memory)) {
2216 int fd;
2217 struct stat info;
2218 const char *base;
Daniel Veillardf1edb102009-08-10 14:43:18 +02002219 if (stat(filename, &info) < 0)
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002220 return;
2221 if ((fd = open(filename, O_RDONLY)) < 0)
2222 return;
2223 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
2224 if (base == (void *) MAP_FAILED)
2225 return;
2226
2227 doc = htmlReadMemory((char *) base, info.st_size, filename,
2228 NULL, options);
Daniel Veillardf1edb102009-08-10 14:43:18 +02002229
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002230 munmap((char *) base, info.st_size);
2231 close(fd);
2232 }
2233#endif
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002234 else if (html) {
Daniel Veillard9475a352003-09-26 12:47:50 +00002235 doc = htmlReadFile(filename, NULL, options);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002236 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002237#endif /* LIBXML_HTML_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002238 else {
Daniel Veillard73b013f2003-09-30 12:36:01 +00002239#ifdef LIBXML_PUSH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002240 /*
2241 * build an XML tree from a string;
2242 */
2243 if (push) {
2244 FILE *f;
2245
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002246 /* '-' Usually means stdin -<sven@zen.org> */
2247 if ((filename[0] == '-') && (filename[1] == 0)) {
2248 f = stdin;
2249 } else {
William M. Brack3403add2004-06-27 02:07:51 +00002250#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2251 f = fopen(filename, "rb");
2252#else
2253 f = fopen(filename, "r");
2254#endif
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002255 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002256 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +00002257 int ret;
Daniel Veillarda880b122003-04-21 21:36:41 +00002258 int res, size = 1024;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002259 char chars[1024];
2260 xmlParserCtxtPtr ctxt;
2261
Daniel Veillarda880b122003-04-21 21:36:41 +00002262 /* if (repeat) size = 1024; */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002263 res = fread(chars, 1, 4, f);
2264 if (res > 0) {
2265 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
2266 chars, res, filename);
Daniel Veillard500a1de2004-03-22 15:22:58 +00002267 xmlCtxtUseOptions(ctxt, options);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002268 while ((res = fread(chars, 1, size, f)) > 0) {
2269 xmlParseChunk(ctxt, chars, res, 0);
2270 }
2271 xmlParseChunk(ctxt, chars, 0, 1);
2272 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +00002273 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002274 xmlFreeParserCtxt(ctxt);
Daniel Veillarde715dd22000-08-29 18:29:38 +00002275 if (!ret) {
2276 xmlFreeDoc(doc);
2277 doc = NULL;
2278 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002279 }
Daniel Veillard84bff682009-09-11 15:30:19 +02002280 if (f != stdin)
2281 fclose(f);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002282 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00002283 } else
2284#endif /* LIBXML_PUSH_ENABLED */
2285 if (testIO) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002286 if ((filename[0] == '-') && (filename[1] == 0)) {
Daniel Veillard60942de2003-09-25 21:05:58 +00002287 doc = xmlReadFd(0, NULL, NULL, options);
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002288 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002289 FILE *f;
Daniel Veillard5e873c42000-04-12 13:27:38 +00002290
William M. Brack3403add2004-06-27 02:07:51 +00002291#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2292 f = fopen(filename, "rb");
2293#else
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002294 f = fopen(filename, "r");
William M. Brack3403add2004-06-27 02:07:51 +00002295#endif
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002296 if (f != NULL) {
2297 if (rectxt == NULL)
2298 doc = xmlReadIO((xmlInputReadCallback) myRead,
2299 (xmlInputCloseCallback) myClose, f,
Daniel Veillard60942de2003-09-25 21:05:58 +00002300 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002301 else
2302 doc = xmlCtxtReadIO(rectxt,
2303 (xmlInputReadCallback) myRead,
2304 (xmlInputCloseCallback) myClose, f,
Daniel Veillard60942de2003-09-25 21:05:58 +00002305 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002306 } else
Daniel Veillard5e873c42000-04-12 13:27:38 +00002307 doc = NULL;
Daniel Veillard5e873c42000-04-12 13:27:38 +00002308 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002309 } else if (htmlout) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002310 xmlParserCtxtPtr ctxt;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002311
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002312 if (rectxt == NULL)
2313 ctxt = xmlNewParserCtxt();
2314 else
2315 ctxt = rectxt;
Daniel Veillardf1edb102009-08-10 14:43:18 +02002316 if (ctxt == NULL) {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002317 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +00002318 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002319 ctxt->sax->error = xmlHTMLError;
2320 ctxt->sax->warning = xmlHTMLWarning;
2321 ctxt->vctxt.error = xmlHTMLValidityError;
2322 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002323
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002324 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002325
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002326 if (rectxt == NULL)
2327 xmlFreeParserCtxt(ctxt);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002328 }
Daniel Veillard46e370e2000-07-21 20:32:03 +00002329#ifdef HAVE_SYS_MMAN_H
2330 } else if (memory) {
2331 int fd;
2332 struct stat info;
2333 const char *base;
Daniel Veillardf1edb102009-08-10 14:43:18 +02002334 if (stat(filename, &info) < 0)
Daniel Veillard46e370e2000-07-21 20:32:03 +00002335 return;
2336 if ((fd = open(filename, O_RDONLY)) < 0)
2337 return;
2338 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillard29579362000-08-14 17:57:48 +00002339 if (base == (void *) MAP_FAILED)
Daniel Veillard46e370e2000-07-21 20:32:03 +00002340 return;
2341
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002342 if (rectxt == NULL)
Daniel Veillard60942de2003-09-25 21:05:58 +00002343 doc = xmlReadMemory((char *) base, info.st_size,
2344 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002345 else
Daniel Veillard60942de2003-09-25 21:05:58 +00002346 doc = xmlCtxtReadMemory(rectxt, (char *) base, info.st_size,
2347 filename, NULL, options);
Daniel Veillardf1edb102009-08-10 14:43:18 +02002348
Daniel Veillard46e370e2000-07-21 20:32:03 +00002349 munmap((char *) base, info.st_size);
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002350 close(fd);
Daniel Veillard46e370e2000-07-21 20:32:03 +00002351#endif
Daniel Veillard4432df22003-09-28 18:58:27 +00002352#ifdef LIBXML_VALID_ENABLED
Daniel Veillardea7751d2002-12-20 00:16:24 +00002353 } else if (valid) {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002354 xmlParserCtxtPtr ctxt = NULL;
Daniel Veillardea7751d2002-12-20 00:16:24 +00002355
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002356 if (rectxt == NULL)
2357 ctxt = xmlNewParserCtxt();
2358 else
2359 ctxt = rectxt;
Daniel Veillardf1edb102009-08-10 14:43:18 +02002360 if (ctxt == NULL) {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002361 doc = NULL;
Daniel Veillardea7751d2002-12-20 00:16:24 +00002362 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002363 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
2364
2365 if (ctxt->valid == 0)
William M. Brack8304d872004-06-08 13:29:32 +00002366 progresult = XMLLINT_ERR_RDFILE;
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002367 if (rectxt == NULL)
2368 xmlFreeParserCtxt(ctxt);
Daniel Veillardea7751d2002-12-20 00:16:24 +00002369 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002370#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardea7751d2002-12-20 00:16:24 +00002371 } else {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002372 if (rectxt != NULL)
2373 doc = xmlCtxtReadFile(rectxt, filename, NULL, options);
Daniel Veillard81562d22005-06-15 13:27:56 +00002374 else {
2375#ifdef LIBXML_SAX1_ENABLED
2376 if (sax1)
2377 doc = xmlParseFile(filename);
2378 else
2379#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002380 doc = xmlReadFile(filename, NULL, options);
Daniel Veillard81562d22005-06-15 13:27:56 +00002381 }
Daniel Veillardea7751d2002-12-20 00:16:24 +00002382 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002383 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002384
Daniel Veillard88a172f2000-08-04 18:23:10 +00002385 /*
2386 * If we don't have a document we might as well give up. Do we
2387 * want an error message here? <sven@zen.org> */
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002388 if (doc == NULL) {
William M. Brack8304d872004-06-08 13:29:32 +00002389 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard88a172f2000-08-04 18:23:10 +00002390 return;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002391 }
2392
Daniel Veillard48b2f892001-02-25 16:11:03 +00002393 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002394 endTimer("Parsing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002395 }
2396
Daniel Veillard29e43992001-12-13 22:21:58 +00002397 /*
2398 * Remove DOCTYPE nodes
2399 */
2400 if (dropdtd) {
2401 xmlDtdPtr dtd;
2402
2403 dtd = xmlGetIntSubset(doc);
2404 if (dtd != NULL) {
2405 xmlUnlinkNode((xmlNodePtr)dtd);
2406 xmlFreeDtd(dtd);
2407 }
2408 }
2409
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002410#ifdef LIBXML_XINCLUDE_ENABLED
Daniel Veillard48b2f892001-02-25 16:11:03 +00002411 if (xinclude) {
2412 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002413 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002414 }
William M. Brack4e1c2db2005-02-11 10:58:55 +00002415 if (xmlXIncludeProcessFlags(doc, options) < 0)
2416 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard48b2f892001-02-25 16:11:03 +00002417 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002418 endTimer("Xinclude processing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002419 }
2420 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002421#endif
Daniel Veillard88a172f2000-08-04 18:23:10 +00002422
Daniel Veillard1934b0c2009-10-07 10:25:06 +02002423#ifdef LIBXML_XPATH_ENABLED
2424 if (xpathquery != NULL) {
2425 doXPathQuery(doc, xpathquery);
2426 }
2427#endif
2428
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002429#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00002430#ifdef LIBXML_XPATH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002431 /*
Daniel Veillardcbaf3992001-12-31 16:16:02 +00002432 * shell interaction
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002433 */
Daniel Veillard26a45c82006-10-20 12:55:34 +00002434 if (shell) {
2435 xmlXPathOrderDocElems(doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002436 xmlShell(doc, filename, xmlShellReadline, stdout);
Daniel Veillard26a45c82006-10-20 12:55:34 +00002437 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002438#endif
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00002439#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002440
Daniel Veillard652327a2003-09-29 18:02:38 +00002441#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002442 /*
2443 * test intermediate copy if needed.
2444 */
2445 if (copy) {
2446 tmp = doc;
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002447 if (timing) {
2448 startTimer();
2449 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002450 doc = xmlCopyDoc(doc, 1);
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002451 if (timing) {
2452 endTimer("Copying");
2453 }
2454 if (timing) {
2455 startTimer();
2456 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002457 xmlFreeDoc(tmp);
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002458 if (timing) {
2459 endTimer("Freeing original");
2460 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002461 }
Daniel Veillard652327a2003-09-29 18:02:38 +00002462#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002463
Daniel Veillard4432df22003-09-28 18:58:27 +00002464#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002465 if ((insert) && (!html)) {
2466 const xmlChar* list[256];
2467 int nb, i;
2468 xmlNodePtr node;
2469
2470 if (doc->children != NULL) {
2471 node = doc->children;
2472 while ((node != NULL) && (node->last == NULL)) node = node->next;
2473 if (node != NULL) {
2474 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
2475 if (nb < 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002476 fprintf(stderr, "could not get valid list of elements\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002477 } else if (nb == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002478 fprintf(stderr, "No element can be inserted under root\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002479 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002480 fprintf(stderr, "%d element types can be inserted under root:\n",
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002481 nb);
2482 for (i = 0;i < nb;i++) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002483 fprintf(stderr, "%s\n", (char *) list[i]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002484 }
2485 }
2486 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02002487 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002488 }else
2489#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002490#ifdef LIBXML_READER_ENABLED
2491 if (walker) {
2492 walkDoc(doc);
2493 }
2494#endif /* LIBXML_READER_ENABLED */
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002495#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard4432df22003-09-28 18:58:27 +00002496 if (noout == 0) {
Daniel Veillard3df01182003-12-10 10:17:51 +00002497 int ret;
2498
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002499 /*
2500 * print it.
2501 */
2502#ifdef LIBXML_DEBUG_ENABLED
2503 if (!debug) {
2504#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00002505 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002506 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002507 }
Daniel Veillard656ce942004-04-30 23:11:45 +00002508#ifdef LIBXML_HTML_ENABLED
Daniel Veillard42fd4122003-11-04 08:47:48 +00002509 if ((html) && (!xmlout)) {
2510 if (compress) {
2511 htmlSaveFile(output ? output : "-", doc);
2512 }
2513 else if (encoding != NULL) {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002514 if (format == 1) {
Daniel Veillard42fd4122003-11-04 08:47:48 +00002515 htmlSaveFileFormat(output ? output : "-", doc, encoding, 1);
2516 }
2517 else {
2518 htmlSaveFileFormat(output ? output : "-", doc, encoding, 0);
2519 }
2520 }
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002521 else if (format == 1) {
Daniel Veillard42fd4122003-11-04 08:47:48 +00002522 htmlSaveFileFormat(output ? output : "-", doc, NULL, 1);
2523 }
2524 else {
2525 FILE *out;
2526 if (output == NULL)
2527 out = stdout;
2528 else {
2529 out = fopen(output,"wb");
2530 }
2531 if (out != NULL) {
2532 if (htmlDocDump(out, doc) < 0)
William M. Brack8304d872004-06-08 13:29:32 +00002533 progresult = XMLLINT_ERR_OUT;
Daniel Veillard42fd4122003-11-04 08:47:48 +00002534
2535 if (output != NULL)
2536 fclose(out);
2537 } else {
2538 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00002539 progresult = XMLLINT_ERR_OUT;
Daniel Veillard42fd4122003-11-04 08:47:48 +00002540 }
2541 }
2542 if ((timing) && (!repeat)) {
2543 endTimer("Saving");
2544 }
2545 } else
2546#endif
Daniel Veillard25048d82004-08-14 22:37:54 +00002547#ifdef LIBXML_C14N_ENABLED
2548 if (canonical) {
2549 xmlChar *result = NULL;
2550 int size;
2551
Aleksey Sanin83868242009-07-09 10:26:22 +02002552 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_0, NULL, 1, &result);
2553 if (size >= 0) {
Stefan Kostdff8d0f2011-05-09 12:14:59 +03002554 if (write(1, result, size) == -1) {
2555 fprintf(stderr, "Can't write data\n");
2556 }
Aleksey Sanin83868242009-07-09 10:26:22 +02002557 xmlFree(result);
2558 } else {
2559 fprintf(stderr, "Failed to canonicalize\n");
2560 progresult = XMLLINT_ERR_OUT;
2561 }
2562 } else if (canonical) {
2563 xmlChar *result = NULL;
2564 int size;
2565
2566 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_1, NULL, 1, &result);
Daniel Veillard25048d82004-08-14 22:37:54 +00002567 if (size >= 0) {
Stefan Kostdff8d0f2011-05-09 12:14:59 +03002568 if (write(1, result, size) == -1) {
2569 fprintf(stderr, "Can't write data\n");
2570 }
Daniel Veillard25048d82004-08-14 22:37:54 +00002571 xmlFree(result);
2572 } else {
2573 fprintf(stderr, "Failed to canonicalize\n");
2574 progresult = XMLLINT_ERR_OUT;
2575 }
2576 } else
Aleksey Sanin2650df12005-06-06 17:16:50 +00002577 if (exc_canonical) {
2578 xmlChar *result = NULL;
2579 int size;
2580
Aleksey Sanin83868242009-07-09 10:26:22 +02002581 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_EXCLUSIVE_1_0, NULL, 1, &result);
Aleksey Sanin2650df12005-06-06 17:16:50 +00002582 if (size >= 0) {
Stefan Kostdff8d0f2011-05-09 12:14:59 +03002583 if (write(1, result, size) == -1) {
2584 fprintf(stderr, "Can't write data\n");
2585 }
Aleksey Sanin2650df12005-06-06 17:16:50 +00002586 xmlFree(result);
2587 } else {
2588 fprintf(stderr, "Failed to canonicalize\n");
2589 progresult = XMLLINT_ERR_OUT;
2590 }
2591 } else
Daniel Veillard25048d82004-08-14 22:37:54 +00002592#endif
Daniel Veillard3b2c2612001-04-04 00:09:00 +00002593#ifdef HAVE_SYS_MMAN_H
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002594 if (memory) {
2595 xmlChar *result;
2596 int len;
2597
2598 if (encoding != NULL) {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002599 if (format == 1) {
Daniel Veillardd536f702001-11-08 17:32:47 +00002600 xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
Daniel Veillardf1edb102009-08-10 14:43:18 +02002601 } else {
Daniel Veillardd536f702001-11-08 17:32:47 +00002602 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
2603 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002604 } else {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002605 if (format == 1)
Daniel Veillard90493a92001-08-14 14:12:47 +00002606 xmlDocDumpFormatMemory(doc, &result, &len, 1);
2607 else
2608 xmlDocDumpMemory(doc, &result, &len);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002609 }
2610 if (result == NULL) {
2611 fprintf(stderr, "Failed to save\n");
Daniel Veillard25048d82004-08-14 22:37:54 +00002612 progresult = XMLLINT_ERR_OUT;
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002613 } else {
Stefan Kostdff8d0f2011-05-09 12:14:59 +03002614 if (write(1, result, len) == -1) {
2615 fprintf(stderr, "Can't write data\n");
2616 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002617 xmlFree(result);
2618 }
Daniel Veillarddab39b52006-10-16 23:22:10 +00002619
Daniel Veillard3b2c2612001-04-04 00:09:00 +00002620 } else
2621#endif /* HAVE_SYS_MMAN_H */
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002622 if (compress) {
2623 xmlSaveFile(output ? output : "-", doc);
Daniel Veillarddab39b52006-10-16 23:22:10 +00002624 } else if (oldout) {
2625 if (encoding != NULL) {
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002626 if (format == 1) {
Daniel Veillarddab39b52006-10-16 23:22:10 +00002627 ret = xmlSaveFormatFileEnc(output ? output : "-", doc,
2628 encoding, 1);
2629 }
2630 else {
2631 ret = xmlSaveFileEnc(output ? output : "-", doc,
2632 encoding);
2633 }
2634 if (ret < 0) {
2635 fprintf(stderr, "failed save to %s\n",
2636 output ? output : "-");
2637 progresult = XMLLINT_ERR_OUT;
2638 }
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002639 } else if (format == 1) {
Daniel Veillarddab39b52006-10-16 23:22:10 +00002640 ret = xmlSaveFormatFile(output ? output : "-", doc, 1);
2641 if (ret < 0) {
2642 fprintf(stderr, "failed save to %s\n",
2643 output ? output : "-");
2644 progresult = XMLLINT_ERR_OUT;
2645 }
Daniel Veillard05d987b2003-10-08 11:54:57 +00002646 } else {
Daniel Veillarddab39b52006-10-16 23:22:10 +00002647 FILE *out;
2648 if (output == NULL)
2649 out = stdout;
2650 else {
2651 out = fopen(output,"wb");
2652 }
2653 if (out != NULL) {
2654 if (xmlDocDump(out, doc) < 0)
2655 progresult = XMLLINT_ERR_OUT;
2656
2657 if (output != NULL)
2658 fclose(out);
2659 } else {
2660 fprintf(stderr, "failed to open %s\n", output);
2661 progresult = XMLLINT_ERR_OUT;
2662 }
2663 }
2664 } else {
2665 xmlSaveCtxtPtr ctxt;
2666 int saveOpts = 0;
2667
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01002668 if (format == 1)
Daniel Veillarddab39b52006-10-16 23:22:10 +00002669 saveOpts |= XML_SAVE_FORMAT;
Adam Spraggd2e62312010-11-03 15:33:40 +01002670 else if (format == 2)
2671 saveOpts |= XML_SAVE_WSNONSIG;
Daniel Veillard9ccea572010-03-10 15:02:49 +01002672
2673#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
Daniel Veillard9d962642009-08-23 15:31:18 +02002674 if (xmlout)
2675 saveOpts |= XML_SAVE_AS_XML;
Daniel Veillard9ccea572010-03-10 15:02:49 +01002676#endif
Daniel Veillarddab39b52006-10-16 23:22:10 +00002677
2678 if (output == NULL)
2679 ctxt = xmlSaveToFd(1, encoding, saveOpts);
2680 else
2681 ctxt = xmlSaveToFilename(output, encoding, saveOpts);
2682
2683 if (ctxt != NULL) {
2684 if (xmlSaveDoc(ctxt, doc) < 0) {
2685 fprintf(stderr, "failed save to %s\n",
2686 output ? output : "-");
2687 progresult = XMLLINT_ERR_OUT;
2688 }
2689 xmlSaveClose(ctxt);
2690 } else {
William M. Brack8304d872004-06-08 13:29:32 +00002691 progresult = XMLLINT_ERR_OUT;
Daniel Veillard05d987b2003-10-08 11:54:57 +00002692 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002693 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002694 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002695 endTimer("Saving");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002696 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002697#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002698 } else {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002699 FILE *out;
2700 if (output == NULL)
2701 out = stdout;
2702 else {
2703 out = fopen(output,"wb");
2704 }
Daniel Veillard05d987b2003-10-08 11:54:57 +00002705 if (out != NULL) {
2706 xmlDebugDumpDocument(out, doc);
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002707
Daniel Veillard05d987b2003-10-08 11:54:57 +00002708 if (output != NULL)
2709 fclose(out);
2710 } else {
2711 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00002712 progresult = XMLLINT_ERR_OUT;
Daniel Veillard05d987b2003-10-08 11:54:57 +00002713 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002714 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002715#endif
2716 }
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002717#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002718
Daniel Veillard4432df22003-09-28 18:58:27 +00002719#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002720 /*
2721 * A posteriori validation test
2722 */
Daniel Veillard66f68e72003-08-18 16:39:51 +00002723 if ((dtdvalid != NULL) || (dtdvalidfpi != NULL)) {
Daniel Veillardcd429612000-10-11 15:57:05 +00002724 xmlDtdPtr dtd;
2725
Daniel Veillard48b2f892001-02-25 16:11:03 +00002726 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002727 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002728 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00002729 if (dtdvalid != NULL)
Daniel Veillardf1edb102009-08-10 14:43:18 +02002730 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
Daniel Veillard66f68e72003-08-18 16:39:51 +00002731 else
Daniel Veillardf1edb102009-08-10 14:43:18 +02002732 dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL);
Daniel Veillard48b2f892001-02-25 16:11:03 +00002733 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002734 endTimer("Parsing DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002735 }
Daniel Veillardcd429612000-10-11 15:57:05 +00002736 if (dtd == NULL) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00002737 if (dtdvalid != NULL)
2738 xmlGenericError(xmlGenericErrorContext,
2739 "Could not parse DTD %s\n", dtdvalid);
2740 else
2741 xmlGenericError(xmlGenericErrorContext,
2742 "Could not parse DTD %s\n", dtdvalidfpi);
William M. Brack8304d872004-06-08 13:29:32 +00002743 progresult = XMLLINT_ERR_DTD;
Daniel Veillardcd429612000-10-11 15:57:05 +00002744 } else {
Daniel Veillarda37aab82003-06-09 09:10:36 +00002745 xmlValidCtxtPtr cvp;
2746
2747 if ((cvp = xmlNewValidCtxt()) == NULL) {
2748 xmlGenericError(xmlGenericErrorContext,
2749 "Couldn't allocate validation context\n");
2750 exit(-1);
2751 }
2752 cvp->userData = (void *) stderr;
2753 cvp->error = (xmlValidityErrorFunc) fprintf;
2754 cvp->warning = (xmlValidityWarningFunc) fprintf;
2755
Daniel Veillard48b2f892001-02-25 16:11:03 +00002756 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002757 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002758 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002759 if (!xmlValidateDtd(cvp, doc, dtd)) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00002760 if (dtdvalid != NULL)
2761 xmlGenericError(xmlGenericErrorContext,
2762 "Document %s does not validate against %s\n",
2763 filename, dtdvalid);
2764 else
2765 xmlGenericError(xmlGenericErrorContext,
2766 "Document %s does not validate against %s\n",
2767 filename, dtdvalidfpi);
William M. Brack8304d872004-06-08 13:29:32 +00002768 progresult = XMLLINT_ERR_VALID;
Daniel Veillardcd429612000-10-11 15:57:05 +00002769 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002770 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002771 endTimer("Validating against DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002772 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002773 xmlFreeValidCtxt(cvp);
Daniel Veillardcd429612000-10-11 15:57:05 +00002774 xmlFreeDtd(dtd);
2775 }
2776 } else if (postvalid) {
Daniel Veillarda37aab82003-06-09 09:10:36 +00002777 xmlValidCtxtPtr cvp;
2778
2779 if ((cvp = xmlNewValidCtxt()) == NULL) {
2780 xmlGenericError(xmlGenericErrorContext,
2781 "Couldn't allocate validation context\n");
2782 exit(-1);
2783 }
2784
Daniel Veillard48b2f892001-02-25 16:11:03 +00002785 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002786 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002787 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002788 cvp->userData = (void *) stderr;
2789 cvp->error = (xmlValidityErrorFunc) fprintf;
2790 cvp->warning = (xmlValidityWarningFunc) fprintf;
2791 if (!xmlValidateDocument(cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00002792 xmlGenericError(xmlGenericErrorContext,
2793 "Document %s does not validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002794 progresult = XMLLINT_ERR_VALID;
Daniel Veillardcd429612000-10-11 15:57:05 +00002795 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002796 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002797 endTimer("Validating");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002798 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002799 xmlFreeValidCtxt(cvp);
Daniel Veillard4432df22003-09-28 18:58:27 +00002800 }
2801#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardd4501d72005-07-24 14:27:16 +00002802#ifdef LIBXML_SCHEMATRON_ENABLED
2803 if (wxschematron != NULL) {
2804 xmlSchematronValidCtxtPtr ctxt;
2805 int ret;
Daniel Veillardc740a172005-07-31 12:17:24 +00002806 int flag;
Daniel Veillardd4501d72005-07-24 14:27:16 +00002807
2808 if ((timing) && (!repeat)) {
2809 startTimer();
2810 }
2811
2812 if (debug)
2813 flag = XML_SCHEMATRON_OUT_XML;
Daniel Veillardc740a172005-07-31 12:17:24 +00002814 else
2815 flag = XML_SCHEMATRON_OUT_TEXT;
2816 if (noout)
2817 flag |= XML_SCHEMATRON_OUT_QUIET;
Daniel Veillardd4501d72005-07-24 14:27:16 +00002818 ctxt = xmlSchematronNewValidCtxt(wxschematron, flag);
2819#if 0
2820 xmlSchematronSetValidErrors(ctxt,
2821 (xmlSchematronValidityErrorFunc) fprintf,
2822 (xmlSchematronValidityWarningFunc) fprintf,
2823 stderr);
2824#endif
2825 ret = xmlSchematronValidateDoc(ctxt, doc);
2826 if (ret == 0) {
2827 fprintf(stderr, "%s validates\n", filename);
2828 } else if (ret > 0) {
2829 fprintf(stderr, "%s fails to validate\n", filename);
2830 progresult = XMLLINT_ERR_VALID;
2831 } else {
2832 fprintf(stderr, "%s validation generated an internal error\n",
2833 filename);
2834 progresult = XMLLINT_ERR_VALID;
2835 }
2836 xmlSchematronFreeValidCtxt(ctxt);
2837 if ((timing) && (!repeat)) {
2838 endTimer("Validating");
2839 }
2840 }
2841#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00002842#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard4432df22003-09-28 18:58:27 +00002843 if (relaxngschemas != NULL) {
Daniel Veillard71531f32003-02-05 13:19:53 +00002844 xmlRelaxNGValidCtxtPtr ctxt;
2845 int ret;
2846
Daniel Veillard42f12e92003-03-07 18:32:59 +00002847 if ((timing) && (!repeat)) {
2848 startTimer();
2849 }
2850
Daniel Veillard71531f32003-02-05 13:19:53 +00002851 ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
2852 xmlRelaxNGSetValidErrors(ctxt,
2853 (xmlRelaxNGValidityErrorFunc) fprintf,
2854 (xmlRelaxNGValidityWarningFunc) fprintf,
2855 stderr);
2856 ret = xmlRelaxNGValidateDoc(ctxt, doc);
2857 if (ret == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002858 fprintf(stderr, "%s validates\n", filename);
Daniel Veillard71531f32003-02-05 13:19:53 +00002859 } else if (ret > 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002860 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002861 progresult = XMLLINT_ERR_VALID;
Daniel Veillard71531f32003-02-05 13:19:53 +00002862 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002863 fprintf(stderr, "%s validation generated an internal error\n",
Daniel Veillard71531f32003-02-05 13:19:53 +00002864 filename);
William M. Brack8304d872004-06-08 13:29:32 +00002865 progresult = XMLLINT_ERR_VALID;
Daniel Veillard71531f32003-02-05 13:19:53 +00002866 }
2867 xmlRelaxNGFreeValidCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00002868 if ((timing) && (!repeat)) {
2869 endTimer("Validating");
2870 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002871 } else if (wxschemas != NULL) {
2872 xmlSchemaValidCtxtPtr ctxt;
2873 int ret;
2874
2875 if ((timing) && (!repeat)) {
2876 startTimer();
2877 }
2878
2879 ctxt = xmlSchemaNewValidCtxt(wxschemas);
2880 xmlSchemaSetValidErrors(ctxt,
2881 (xmlSchemaValidityErrorFunc) fprintf,
2882 (xmlSchemaValidityWarningFunc) fprintf,
2883 stderr);
2884 ret = xmlSchemaValidateDoc(ctxt, doc);
2885 if (ret == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002886 fprintf(stderr, "%s validates\n", filename);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002887 } else if (ret > 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002888 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002889 progresult = XMLLINT_ERR_VALID;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002890 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002891 fprintf(stderr, "%s validation generated an internal error\n",
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002892 filename);
William M. Brack8304d872004-06-08 13:29:32 +00002893 progresult = XMLLINT_ERR_VALID;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002894 }
2895 xmlSchemaFreeValidCtxt(ctxt);
2896 if ((timing) && (!repeat)) {
2897 endTimer("Validating");
2898 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002899 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002900#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002901
2902#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillard6b099012008-11-06 13:47:39 +00002903#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002904 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00002905 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002906#endif
Daniel Veillard6b099012008-11-06 13:47:39 +00002907#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002908
2909 /*
2910 * free it.
2911 */
Daniel Veillard48b2f892001-02-25 16:11:03 +00002912 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002913 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002914 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002915 xmlFreeDoc(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +00002916 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002917 endTimer("Freeing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002918 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002919}
2920
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002921/************************************************************************
Daniel Veillardf1edb102009-08-10 14:43:18 +02002922 * *
2923 * Usage and Main *
2924 * *
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002925 ************************************************************************/
2926
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002927static void showVersion(const char *name) {
2928 fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
2929 fprintf(stderr, " compiled with: ");
Daniel Veillard602434d2005-09-12 09:20:31 +00002930 if (xmlHasFeature(XML_WITH_THREAD)) fprintf(stderr, "Threads ");
2931 if (xmlHasFeature(XML_WITH_TREE)) fprintf(stderr, "Tree ");
2932 if (xmlHasFeature(XML_WITH_OUTPUT)) fprintf(stderr, "Output ");
2933 if (xmlHasFeature(XML_WITH_PUSH)) fprintf(stderr, "Push ");
2934 if (xmlHasFeature(XML_WITH_READER)) fprintf(stderr, "Reader ");
2935 if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(stderr, "Patterns ");
2936 if (xmlHasFeature(XML_WITH_WRITER)) fprintf(stderr, "Writer ");
2937 if (xmlHasFeature(XML_WITH_SAX1)) fprintf(stderr, "SAXv1 ");
Daniel Veillardf1edb102009-08-10 14:43:18 +02002938 if (xmlHasFeature(XML_WITH_FTP)) fprintf(stderr, "FTP ");
2939 if (xmlHasFeature(XML_WITH_HTTP)) fprintf(stderr, "HTTP ");
Daniel Veillard602434d2005-09-12 09:20:31 +00002940 if (xmlHasFeature(XML_WITH_VALID)) fprintf(stderr, "DTDValid ");
Daniel Veillardf1edb102009-08-10 14:43:18 +02002941 if (xmlHasFeature(XML_WITH_HTML)) fprintf(stderr, "HTML ");
2942 if (xmlHasFeature(XML_WITH_LEGACY)) fprintf(stderr, "Legacy ");
2943 if (xmlHasFeature(XML_WITH_C14N)) fprintf(stderr, "C14N ");
2944 if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(stderr, "Catalog ");
2945 if (xmlHasFeature(XML_WITH_XPATH)) fprintf(stderr, "XPath ");
2946 if (xmlHasFeature(XML_WITH_XPTR)) fprintf(stderr, "XPointer ");
2947 if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(stderr, "XInclude ");
2948 if (xmlHasFeature(XML_WITH_ICONV)) fprintf(stderr, "Iconv ");
2949 if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(stderr, "ISO8859X ");
2950 if (xmlHasFeature(XML_WITH_UNICODE)) fprintf(stderr, "Unicode ");
2951 if (xmlHasFeature(XML_WITH_REGEXP)) fprintf(stderr, "Regexps ");
2952 if (xmlHasFeature(XML_WITH_AUTOMATA)) fprintf(stderr, "Automata ");
2953 if (xmlHasFeature(XML_WITH_EXPR)) fprintf(stderr, "Expr ");
2954 if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(stderr, "Schemas ");
2955 if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(stderr, "Schematron ");
2956 if (xmlHasFeature(XML_WITH_MODULES)) fprintf(stderr, "Modules ");
2957 if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(stderr, "Debug ");
2958 if (xmlHasFeature(XML_WITH_DEBUG_MEM)) fprintf(stderr, "MemDebug ");
2959 if (xmlHasFeature(XML_WITH_DEBUG_RUN)) fprintf(stderr, "RunDebug ");
Daniel Veillard75acfee2006-07-13 06:29:56 +00002960 if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(stderr, "Zlib ");
Anders F Bjorklundeae52612011-09-18 16:59:13 +02002961 if (xmlHasFeature(XML_WITH_LZMA)) fprintf(stderr, "Lzma ");
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002962 fprintf(stderr, "\n");
2963}
2964
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002965static void usage(const char *name) {
2966 printf("Usage : %s [options] XMLfiles ...\n", name);
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002967#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002968 printf("\tParse the XML files and output the result of the parsing\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002969#else
2970 printf("\tParse the XML files\n");
2971#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002972 printf("\t--version : display the version of the XML library used\n");
2973#ifdef LIBXML_DEBUG_ENABLED
2974 printf("\t--debug : dump a debug tree of the in-memory document\n");
2975 printf("\t--shell : run a navigating shell\n");
2976 printf("\t--debugent : debug the entities defined in the document\n");
Daniel Veillard8326e732003-01-07 00:19:07 +00002977#else
Daniel Veillard81273902003-09-30 00:43:48 +00002978#ifdef LIBXML_READER_ENABLED
Daniel Veillard8326e732003-01-07 00:19:07 +00002979 printf("\t--debug : dump the nodes content when using --stream\n");
Daniel Veillard81273902003-09-30 00:43:48 +00002980#endif /* LIBXML_READER_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002981#endif
Daniel Veillard652327a2003-09-29 18:02:38 +00002982#ifdef LIBXML_TREE_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002983 printf("\t--copy : used to test the internal copy implementation\n");
Daniel Veillard652327a2003-09-29 18:02:38 +00002984#endif /* LIBXML_TREE_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002985 printf("\t--recover : output what was parsable on broken XML documents\n");
Daniel Veillard8915c152008-08-26 13:05:34 +00002986 printf("\t--huge : remove any internal arbitrary parser limits\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002987 printf("\t--noent : substitute entity references by their value\n");
Daniel Veillardc62efc82011-05-16 16:03:50 +08002988 printf("\t--noenc : ignore any encoding specified inside the document\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002989 printf("\t--noout : don't output the result tree\n");
Daniel Veillard0bff36d2004-08-31 09:37:03 +00002990 printf("\t--path 'paths': provide a set of paths for resources\n");
2991 printf("\t--load-trace : print trace of all external entites loaded\n");
Daniel Veillarde8b09e42003-05-13 22:14:13 +00002992 printf("\t--nonet : refuse to fetch DTDs or entities over network\n");
Daniel Veillard8874b942005-08-25 13:19:21 +00002993 printf("\t--nocompact : do not generate compact text nodes\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002994 printf("\t--htmlout : output results as HTML\n");
Daniel Veillard05c13a22001-09-09 08:38:09 +00002995 printf("\t--nowrap : do not put HTML doc wrapper\n");
Daniel Veillard4432df22003-09-28 18:58:27 +00002996#ifdef LIBXML_VALID_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002997 printf("\t--valid : validate the document in addition to std well-formed check\n");
2998 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
2999 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
Daniel Veillard66f68e72003-08-18 16:39:51 +00003000 printf("\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
Daniel Veillard4432df22003-09-28 18:58:27 +00003001#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003002 printf("\t--timing : print some timings\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003003 printf("\t--output file or -o file: save to a given file\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003004 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
3005 printf("\t--insert : ad-hoc test for valid insertions\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003006#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003007#ifdef HAVE_ZLIB_H
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003008 printf("\t--compress : turn on gzip compression of output\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003009#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003010#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003011#ifdef LIBXML_HTML_ENABLED
3012 printf("\t--html : use the HTML parser\n");
Daniel Veillard42fd4122003-11-04 08:47:48 +00003013 printf("\t--xmlout : force to use the XML serializer when using --html\n");
Daniel Veillardf1121c42010-07-26 14:02:42 +02003014 printf("\t--nodefdtd : do not default HTML doctype\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003015#endif
Daniel Veillard73b013f2003-09-30 12:36:01 +00003016#ifdef LIBXML_PUSH_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003017 printf("\t--push : use the push mode of the parser\n");
Daniel Veillard73b013f2003-09-30 12:36:01 +00003018#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003019#ifdef HAVE_SYS_MMAN_H
3020 printf("\t--memory : parse from memory\n");
3021#endif
Daniel Veillard87076042004-05-03 22:54:49 +00003022 printf("\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003023 printf("\t--nowarning : do not emit warnings from parser/validator\n");
3024 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
Daniel Veillarddca8cc72003-09-26 13:53:14 +00003025 printf("\t--nocdata : replace cdata section with text nodes\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003026#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard90493a92001-08-14 14:12:47 +00003027 printf("\t--format : reformat/reindent the input\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003028 printf("\t--encode encoding : output in the given encoding\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003029 printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
Adam Spraggd2e62312010-11-03 15:33:40 +01003030 printf("\t--pretty STYLE : pretty-print in a particular style\n");
3031 printf("\t 0 Do not pretty print\n");
3032 printf("\t 1 Format the XML content, as --format\n");
3033 printf("\t 2 Add whitespace inside tags, preserving content\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003034#endif /* LIBXML_OUTPUT_ENABLED */
Aleksey Sanin83868242009-07-09 10:26:22 +02003035 printf("\t--c14n : save in W3C canonical format v1.0 (with comments)\n");
3036 printf("\t--c14n11 : save in W3C canonical format v1.1 (with comments)\n");
Aleksey Sanin2650df12005-06-06 17:16:50 +00003037 printf("\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n");
Daniel Veillard25048d82004-08-14 22:37:54 +00003038#ifdef LIBXML_C14N_ENABLED
3039#endif /* LIBXML_C14N_ENABLED */
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003040 printf("\t--nsclean : remove redundant namespace declarations\n");
3041 printf("\t--testIO : test user I/O support\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003042#ifdef LIBXML_CATALOG_ENABLED
Daniel Veillardbd9b0e82001-11-26 10:32:08 +00003043 printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
3044 printf("\t otherwise XML Catalogs starting from \n");
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003045 printf("\t %s are activated by default\n", XML_XML_DEFAULT_CATALOG);
Daniel Veillard05c13a22001-09-09 08:38:09 +00003046 printf("\t--nocatalogs: deactivate all catalogs\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003047#endif
3048 printf("\t--auto : generate a small doc on the fly\n");
3049#ifdef LIBXML_XINCLUDE_ENABLED
3050 printf("\t--xinclude : do XInclude processing\n");
Daniel Veillardc14c3892004-08-16 12:34:50 +00003051 printf("\t--noxincludenode : same but do not generate XInclude nodes\n");
Daniel Veillard54bd29b2008-08-26 07:26:55 +00003052 printf("\t--nofixup-base-uris : do not fixup xml:base uris\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003053#endif
Daniel Veillardcbaf3992001-12-31 16:16:02 +00003054 printf("\t--loaddtd : fetch external DTD\n");
Daniel Veillard48da9102001-08-07 01:10:10 +00003055 printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
Daniel Veillard81273902003-09-30 00:43:48 +00003056#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003057 printf("\t--stream : use the streaming interface to process very large files\n");
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003058 printf("\t--walker : create a reader and walk though the resulting doc\n");
Daniel Veillard81273902003-09-30 00:43:48 +00003059#endif /* LIBXML_READER_ENABLED */
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003060#ifdef LIBXML_PATTERN_ENABLED
3061 printf("\t--pattern pattern_value : test the pattern support\n");
3062#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003063 printf("\t--chkregister : verify the node registration code\n");
Daniel Veillardef4d3bc2003-02-07 12:38:22 +00003064#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard71531f32003-02-05 13:19:53 +00003065 printf("\t--relaxng schema : do RelaxNG validation against the schema\n");
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003066 printf("\t--schema schema : do validation against the WXS schema\n");
Daniel Veillard71531f32003-02-05 13:19:53 +00003067#endif
Daniel Veillarde70375c2005-07-30 21:09:12 +00003068#ifdef LIBXML_SCHEMATRON_ENABLED
3069 printf("\t--schematron schema : do validation against a schematron\n");
3070#endif
Daniel Veillard971771e2005-07-09 17:32:57 +00003071#ifdef LIBXML_SAX1_ENABLED
3072 printf("\t--sax1: use the old SAX1 interfaces for processing\n");
3073#endif
3074 printf("\t--sax: do not build a tree but work just at the SAX level\n");
Daniel Veillard7e5c3f42008-07-29 16:12:31 +00003075 printf("\t--oldxml10: use XML-1.0 parsing rules before the 5th edition\n");
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003076#ifdef LIBXML_XPATH_ENABLED
3077 printf("\t--xpath expr: evaluate the XPath expression, inply --noout\n");
3078#endif
Daniel Veillard971771e2005-07-09 17:32:57 +00003079
Daniel Veillarda42f25f2002-01-25 14:15:40 +00003080 printf("\nLibxml project home page: http://xmlsoft.org/\n");
3081 printf("To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003082}
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003083
3084static void registerNode(xmlNodePtr node)
3085{
3086 node->_private = malloc(sizeof(long));
3087 *(long*)node->_private = (long) 0x81726354;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003088 nbregister++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003089}
3090
3091static void deregisterNode(xmlNodePtr node)
3092{
3093 assert(node->_private != NULL);
3094 assert(*(long*)node->_private == (long) 0x81726354);
3095 free(node->_private);
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003096 nbregister--;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003097}
3098
Daniel Veillard4a6845d2001-01-03 13:32:39 +00003099int
3100main(int argc, char **argv) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00003101 int i, acount;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003102 int files = 0;
Daniel Veillard845cce42002-01-09 11:51:37 +00003103 int version = 0;
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00003104 const char* indent;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003105
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003106 if (argc <= 1) {
3107 usage(argv[0]);
3108 return(1);
3109 }
Daniel Veillardbe803962000-06-28 23:40:59 +00003110 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003111 for (i = 1; i < argc ; i++) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003112 if (!strcmp(argv[i], "-"))
3113 break;
3114
3115 if (argv[i][0] != '-')
3116 continue;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003117 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
3118 debug++;
Daniel Veillard56ada1d2003-01-07 11:17:25 +00003119 else
3120#ifdef LIBXML_DEBUG_ENABLED
3121 if ((!strcmp(argv[i], "-shell")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003122 (!strcmp(argv[i], "--shell"))) {
3123 shell++;
3124 noout = 1;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003125 } else
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003126#endif
Daniel Veillard652327a2003-09-29 18:02:38 +00003127#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003128 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
3129 copy++;
Daniel Veillard652327a2003-09-29 18:02:38 +00003130 else
3131#endif /* LIBXML_TREE_ENABLED */
3132 if ((!strcmp(argv[i], "-recover")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003133 (!strcmp(argv[i], "--recover"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003134 recovery++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003135 options |= XML_PARSE_RECOVER;
Daniel Veillard8915c152008-08-26 13:05:34 +00003136 } else if ((!strcmp(argv[i], "-huge")) ||
3137 (!strcmp(argv[i], "--huge"))) {
3138 options |= XML_PARSE_HUGE;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003139 } else if ((!strcmp(argv[i], "-noent")) ||
3140 (!strcmp(argv[i], "--noent"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003141 noent++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003142 options |= XML_PARSE_NOENT;
Daniel Veillardc62efc82011-05-16 16:03:50 +08003143 } else if ((!strcmp(argv[i], "-noenc")) ||
3144 (!strcmp(argv[i], "--noenc"))) {
3145 noenc++;
3146 options |= XML_PARSE_IGNORE_ENC;
Daniel Veillarddca8cc72003-09-26 13:53:14 +00003147 } else if ((!strcmp(argv[i], "-nsclean")) ||
3148 (!strcmp(argv[i], "--nsclean"))) {
3149 options |= XML_PARSE_NSCLEAN;
3150 } else if ((!strcmp(argv[i], "-nocdata")) ||
3151 (!strcmp(argv[i], "--nocdata"))) {
3152 options |= XML_PARSE_NOCDATA;
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003153 } else if ((!strcmp(argv[i], "-nodict")) ||
3154 (!strcmp(argv[i], "--nodict"))) {
3155 options |= XML_PARSE_NODICT;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003156 } else if ((!strcmp(argv[i], "-version")) ||
Daniel Veillard845cce42002-01-09 11:51:37 +00003157 (!strcmp(argv[i], "--version"))) {
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00003158 showVersion(argv[0]);
Daniel Veillard845cce42002-01-09 11:51:37 +00003159 version = 1;
3160 } else if ((!strcmp(argv[i], "-noout")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003161 (!strcmp(argv[i], "--noout")))
3162 noout++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003163#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003164 else if ((!strcmp(argv[i], "-o")) ||
3165 (!strcmp(argv[i], "-output")) ||
3166 (!strcmp(argv[i], "--output"))) {
3167 i++;
Daniel Veillard6e4f1c02002-04-09 09:55:20 +00003168 output = argv[i];
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003169 }
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003170#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003171 else if ((!strcmp(argv[i], "-htmlout")) ||
3172 (!strcmp(argv[i], "--htmlout")))
3173 htmlout++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003174 else if ((!strcmp(argv[i], "-nowrap")) ||
3175 (!strcmp(argv[i], "--nowrap")))
3176 nowrap++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003177#ifdef LIBXML_HTML_ENABLED
3178 else if ((!strcmp(argv[i], "-html")) ||
3179 (!strcmp(argv[i], "--html"))) {
3180 html++;
3181 }
Daniel Veillard42fd4122003-11-04 08:47:48 +00003182 else if ((!strcmp(argv[i], "-xmlout")) ||
3183 (!strcmp(argv[i], "--xmlout"))) {
3184 xmlout++;
Daniel Veillardf1121c42010-07-26 14:02:42 +02003185 } else if ((!strcmp(argv[i], "-nodefdtd")) ||
3186 (!strcmp(argv[i], "--nodefdtd"))) {
3187 nodefdtd++;
3188 options |= HTML_PARSE_NODEFDTD;
Daniel Veillard42fd4122003-11-04 08:47:48 +00003189 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003190#endif /* LIBXML_HTML_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003191 else if ((!strcmp(argv[i], "-loaddtd")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003192 (!strcmp(argv[i], "--loaddtd"))) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003193 loaddtd++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003194 options |= XML_PARSE_DTDLOAD;
3195 } else if ((!strcmp(argv[i], "-dtdattr")) ||
Daniel Veillard48da9102001-08-07 01:10:10 +00003196 (!strcmp(argv[i], "--dtdattr"))) {
3197 loaddtd++;
3198 dtdattrs++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003199 options |= XML_PARSE_DTDATTR;
Daniel Veillard4432df22003-09-28 18:58:27 +00003200 }
3201#ifdef LIBXML_VALID_ENABLED
3202 else if ((!strcmp(argv[i], "-valid")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003203 (!strcmp(argv[i], "--valid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003204 valid++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003205 options |= XML_PARSE_DTDVALID;
3206 } else if ((!strcmp(argv[i], "-postvalid")) ||
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003207 (!strcmp(argv[i], "--postvalid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003208 postvalid++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003209 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003210 options |= XML_PARSE_DTDLOAD;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003211 } else if ((!strcmp(argv[i], "-dtdvalid")) ||
Daniel Veillardcd429612000-10-11 15:57:05 +00003212 (!strcmp(argv[i], "--dtdvalid"))) {
3213 i++;
3214 dtdvalid = argv[i];
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003215 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003216 options |= XML_PARSE_DTDLOAD;
Daniel Veillard66f68e72003-08-18 16:39:51 +00003217 } else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3218 (!strcmp(argv[i], "--dtdvalidfpi"))) {
3219 i++;
3220 dtdvalidfpi = argv[i];
3221 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003222 options |= XML_PARSE_DTDLOAD;
Daniel Veillardcd429612000-10-11 15:57:05 +00003223 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003224#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard29e43992001-12-13 22:21:58 +00003225 else if ((!strcmp(argv[i], "-dropdtd")) ||
3226 (!strcmp(argv[i], "--dropdtd")))
3227 dropdtd++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003228 else if ((!strcmp(argv[i], "-insert")) ||
3229 (!strcmp(argv[i], "--insert")))
3230 insert++;
Daniel Veillard48b2f892001-02-25 16:11:03 +00003231 else if ((!strcmp(argv[i], "-timing")) ||
3232 (!strcmp(argv[i], "--timing")))
3233 timing++;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00003234 else if ((!strcmp(argv[i], "-auto")) ||
3235 (!strcmp(argv[i], "--auto")))
3236 generate++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003237 else if ((!strcmp(argv[i], "-repeat")) ||
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00003238 (!strcmp(argv[i], "--repeat"))) {
3239 if (repeat)
3240 repeat *= 10;
3241 else
3242 repeat = 100;
Daniel Veillard73b013f2003-09-30 12:36:01 +00003243 }
3244#ifdef LIBXML_PUSH_ENABLED
3245 else if ((!strcmp(argv[i], "-push")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003246 (!strcmp(argv[i], "--push")))
3247 push++;
Daniel Veillard73b013f2003-09-30 12:36:01 +00003248#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillard46e370e2000-07-21 20:32:03 +00003249#ifdef HAVE_SYS_MMAN_H
3250 else if ((!strcmp(argv[i], "-memory")) ||
3251 (!strcmp(argv[i], "--memory")))
3252 memory++;
3253#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +00003254 else if ((!strcmp(argv[i], "-testIO")) ||
3255 (!strcmp(argv[i], "--testIO")))
3256 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003257#ifdef LIBXML_XINCLUDE_ENABLED
3258 else if ((!strcmp(argv[i], "-xinclude")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003259 (!strcmp(argv[i], "--xinclude"))) {
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003260 xinclude++;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003261 options |= XML_PARSE_XINCLUDE;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003262 }
Daniel Veillardc14c3892004-08-16 12:34:50 +00003263 else if ((!strcmp(argv[i], "-noxincludenode")) ||
3264 (!strcmp(argv[i], "--noxincludenode"))) {
3265 xinclude++;
3266 options |= XML_PARSE_XINCLUDE;
3267 options |= XML_PARSE_NOXINCNODE;
3268 }
Daniel Veillard54bd29b2008-08-26 07:26:55 +00003269 else if ((!strcmp(argv[i], "-nofixup-base-uris")) ||
3270 (!strcmp(argv[i], "--nofixup-base-uris"))) {
3271 xinclude++;
3272 options |= XML_PARSE_XINCLUDE;
3273 options |= XML_PARSE_NOBASEFIX;
3274 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003275#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003276#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003277#ifdef HAVE_ZLIB_H
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003278 else if ((!strcmp(argv[i], "-compress")) ||
3279 (!strcmp(argv[i], "--compress"))) {
3280 compress++;
3281 xmlSetCompressMode(9);
3282 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003283#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003284#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003285 else if ((!strcmp(argv[i], "-nowarning")) ||
3286 (!strcmp(argv[i], "--nowarning"))) {
3287 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003288 xmlPedanticParserDefault(0);
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003289 options |= XML_PARSE_NOWARNING;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003290 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003291 else if ((!strcmp(argv[i], "-pedantic")) ||
3292 (!strcmp(argv[i], "--pedantic"))) {
3293 xmlGetWarningsDefaultValue = 1;
3294 xmlPedanticParserDefault(1);
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003295 options |= XML_PARSE_PEDANTIC;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003296 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00003297#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003298 else if ((!strcmp(argv[i], "-debugent")) ||
3299 (!strcmp(argv[i], "--debugent"))) {
3300 debugent++;
3301 xmlParserDebugEntities = 1;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003302 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00003303#endif
Daniel Veillard25048d82004-08-14 22:37:54 +00003304#ifdef LIBXML_C14N_ENABLED
3305 else if ((!strcmp(argv[i], "-c14n")) ||
3306 (!strcmp(argv[i], "--c14n"))) {
3307 canonical++;
3308 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003309 }
Aleksey Sanin83868242009-07-09 10:26:22 +02003310 else if ((!strcmp(argv[i], "-c14n11")) ||
3311 (!strcmp(argv[i], "--c14n11"))) {
3312 canonical_11++;
3313 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003314 }
Aleksey Sanin2650df12005-06-06 17:16:50 +00003315 else if ((!strcmp(argv[i], "-exc-c14n")) ||
3316 (!strcmp(argv[i], "--exc-c14n"))) {
3317 exc_canonical++;
3318 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003319 }
Daniel Veillard25048d82004-08-14 22:37:54 +00003320#endif
Daniel Veillard81418e32001-05-22 15:08:55 +00003321#ifdef LIBXML_CATALOG_ENABLED
3322 else if ((!strcmp(argv[i], "-catalogs")) ||
3323 (!strcmp(argv[i], "--catalogs"))) {
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003324 catalogs++;
3325 } else if ((!strcmp(argv[i], "-nocatalogs")) ||
3326 (!strcmp(argv[i], "--nocatalogs"))) {
3327 nocatalogs++;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003328 }
Daniel Veillard81418e32001-05-22 15:08:55 +00003329#endif
Daniel Veillardbe803962000-06-28 23:40:59 +00003330 else if ((!strcmp(argv[i], "-encode")) ||
3331 (!strcmp(argv[i], "--encode"))) {
3332 i++;
3333 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003334 /*
3335 * OK it's for testing purposes
3336 */
3337 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +00003338 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003339 else if ((!strcmp(argv[i], "-noblanks")) ||
3340 (!strcmp(argv[i], "--noblanks"))) {
3341 noblanks++;
3342 xmlKeepBlanksDefault(0);
Daniel Veillard90493a92001-08-14 14:12:47 +00003343 }
Daniel Veillard87076042004-05-03 22:54:49 +00003344 else if ((!strcmp(argv[i], "-maxmem")) ||
3345 (!strcmp(argv[i], "--maxmem"))) {
3346 i++;
3347 if (sscanf(argv[i], "%d", &maxmem) == 1) {
3348 xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc,
3349 myStrdupFunc);
3350 } else {
3351 maxmem = 0;
3352 }
3353 }
Daniel Veillard90493a92001-08-14 14:12:47 +00003354 else if ((!strcmp(argv[i], "-format")) ||
3355 (!strcmp(argv[i], "--format"))) {
3356 noblanks++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003357#ifdef LIBXML_OUTPUT_ENABLED
Adam Spragg5f9d9ce2010-11-01 14:27:11 +01003358 format = 1;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003359#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard90493a92001-08-14 14:12:47 +00003360 xmlKeepBlanksDefault(0);
Daniel Veillard7704fb12003-01-03 16:19:51 +00003361 }
Adam Spraggd2e62312010-11-03 15:33:40 +01003362 else if ((!strcmp(argv[i], "-pretty")) ||
3363 (!strcmp(argv[i], "--pretty"))) {
3364 i++;
3365#ifdef LIBXML_OUTPUT_ENABLED
3366 format = atoi(argv[i]);
3367#endif /* LIBXML_OUTPUT_ENABLED */
3368 if (format == 1) {
3369 noblanks++;
3370 xmlKeepBlanksDefault(0);
3371 }
3372 }
Daniel Veillard81273902003-09-30 00:43:48 +00003373#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003374 else if ((!strcmp(argv[i], "-stream")) ||
3375 (!strcmp(argv[i], "--stream"))) {
3376 stream++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003377 }
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003378 else if ((!strcmp(argv[i], "-walker")) ||
3379 (!strcmp(argv[i], "--walker"))) {
3380 walker++;
3381 noout++;
3382 }
Daniel Veillard81273902003-09-30 00:43:48 +00003383#endif /* LIBXML_READER_ENABLED */
3384#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +00003385 else if ((!strcmp(argv[i], "-sax1")) ||
3386 (!strcmp(argv[i], "--sax1"))) {
Daniel Veillard023d0ba2009-07-29 11:34:50 +02003387 sax1++;
3388 options |= XML_PARSE_SAX1;
Daniel Veillard07cb8222003-09-10 10:51:05 +00003389 }
Daniel Veillard81273902003-09-30 00:43:48 +00003390#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003391 else if ((!strcmp(argv[i], "-sax")) ||
3392 (!strcmp(argv[i], "--sax"))) {
Daniel Veillard023d0ba2009-07-29 11:34:50 +02003393 sax++;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003394 }
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003395 else if ((!strcmp(argv[i], "-chkregister")) ||
3396 (!strcmp(argv[i], "--chkregister"))) {
Daniel Veillard023d0ba2009-07-29 11:34:50 +02003397 chkregister++;
Daniel Veillard71531f32003-02-05 13:19:53 +00003398#ifdef LIBXML_SCHEMAS_ENABLED
3399 } else if ((!strcmp(argv[i], "-relaxng")) ||
3400 (!strcmp(argv[i], "--relaxng"))) {
3401 i++;
3402 relaxng = argv[i];
3403 noent++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003404 options |= XML_PARSE_NOENT;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003405 } else if ((!strcmp(argv[i], "-schema")) ||
3406 (!strcmp(argv[i], "--schema"))) {
3407 i++;
3408 schema = argv[i];
3409 noent++;
Daniel Veillard71531f32003-02-05 13:19:53 +00003410#endif
Daniel Veillardd4501d72005-07-24 14:27:16 +00003411#ifdef LIBXML_SCHEMATRON_ENABLED
3412 } else if ((!strcmp(argv[i], "-schematron")) ||
3413 (!strcmp(argv[i], "--schematron"))) {
3414 i++;
3415 schematron = argv[i];
3416 noent++;
3417#endif
Daniel Veillarde8b09e42003-05-13 22:14:13 +00003418 } else if ((!strcmp(argv[i], "-nonet")) ||
3419 (!strcmp(argv[i], "--nonet"))) {
Daniel Veillard61b93382003-11-03 14:28:31 +00003420 options |= XML_PARSE_NONET;
Daniel Veillard968d6432006-04-25 16:17:53 +00003421 xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
Daniel Veillard8874b942005-08-25 13:19:21 +00003422 } else if ((!strcmp(argv[i], "-nocompact")) ||
3423 (!strcmp(argv[i], "--nocompact"))) {
3424 options &= ~XML_PARSE_COMPACT;
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003425 } else if ((!strcmp(argv[i], "-load-trace")) ||
3426 (!strcmp(argv[i], "--load-trace"))) {
3427 load_trace++;
3428 } else if ((!strcmp(argv[i], "-path")) ||
3429 (!strcmp(argv[i], "--path"))) {
3430 i++;
3431 parsePath(BAD_CAST argv[i]);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003432#ifdef LIBXML_PATTERN_ENABLED
3433 } else if ((!strcmp(argv[i], "-pattern")) ||
3434 (!strcmp(argv[i], "--pattern"))) {
3435 i++;
3436 pattern = argv[i];
3437#endif
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003438#ifdef LIBXML_XPATH_ENABLED
3439 } else if ((!strcmp(argv[i], "-xpath")) ||
3440 (!strcmp(argv[i], "--xpath"))) {
3441 i++;
3442 noout++;
3443 xpathquery = argv[i];
3444#endif
Daniel Veillard7e5c3f42008-07-29 16:12:31 +00003445 } else if ((!strcmp(argv[i], "-oldxml10")) ||
3446 (!strcmp(argv[i], "--oldxml10"))) {
3447 oldxml10++;
3448 options |= XML_PARSE_OLD10;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003449 } else {
3450 fprintf(stderr, "Unknown option %s\n", argv[i]);
3451 usage(argv[0]);
3452 return(1);
3453 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003454 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003455
3456#ifdef LIBXML_CATALOG_ENABLED
3457 if (nocatalogs == 0) {
3458 if (catalogs) {
3459 const char *catal;
3460
3461 catal = getenv("SGML_CATALOG_FILES");
Daniel Veillard6c5f9d12001-08-25 13:33:14 +00003462 if (catal != NULL) {
3463 xmlLoadCatalogs(catal);
3464 } else {
3465 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
3466 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003467 }
3468 }
3469#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003470
Daniel Veillard81273902003-09-30 00:43:48 +00003471#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +00003472 if (sax1)
3473 xmlSAXDefaultVersion(1);
3474 else
3475 xmlSAXDefaultVersion(2);
Daniel Veillard81273902003-09-30 00:43:48 +00003476#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillard07cb8222003-09-10 10:51:05 +00003477
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003478 if (chkregister) {
3479 xmlRegisterNodeDefault(registerNode);
3480 xmlDeregisterNodeDefault(deregisterNode);
3481 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02003482
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00003483 indent = getenv("XMLLINT_INDENT");
3484 if(indent != NULL) {
3485 xmlTreeIndentString = indent;
3486 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02003487
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003488
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003489 defaultEntityLoader = xmlGetExternalEntityLoader();
3490 xmlSetExternalEntityLoader(xmllintExternalEntityLoader);
3491
Daniel Veillardd9bad132001-07-23 19:39:43 +00003492 xmlLineNumbersDefault(1);
Daniel Veillard48da9102001-08-07 01:10:10 +00003493 if (loaddtd != 0)
3494 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
3495 if (dtdattrs)
3496 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003497 if (noent != 0) xmlSubstituteEntitiesDefault(1);
Daniel Veillard4432df22003-09-28 18:58:27 +00003498#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003499 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
Daniel Veillard4432df22003-09-28 18:58:27 +00003500#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003501 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003502 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003503 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003504 xmlGenericError(xmlGenericErrorContext,
3505 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
3506 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003507 "<html><head><title>%s output</title></head>\n",
3508 argv[0]);
Daniel Veillardf1edb102009-08-10 14:43:18 +02003509 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003510 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
3511 argv[0]);
3512 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003513
Daniel Veillardd4501d72005-07-24 14:27:16 +00003514#ifdef LIBXML_SCHEMATRON_ENABLED
3515 if ((schematron != NULL) && (sax == 0)
3516#ifdef LIBXML_READER_ENABLED
3517 && (stream == 0)
3518#endif /* LIBXML_READER_ENABLED */
3519 ) {
3520 xmlSchematronParserCtxtPtr ctxt;
3521
3522 /* forces loading the DTDs */
Daniel Veillardf1edb102009-08-10 14:43:18 +02003523 xmlLoadExtDtdDefaultValue |= 1;
Daniel Veillardd4501d72005-07-24 14:27:16 +00003524 options |= XML_PARSE_DTDLOAD;
3525 if (timing) {
3526 startTimer();
3527 }
3528 ctxt = xmlSchematronNewParserCtxt(schematron);
3529#if 0
3530 xmlSchematronSetParserErrors(ctxt,
3531 (xmlSchematronValidityErrorFunc) fprintf,
3532 (xmlSchematronValidityWarningFunc) fprintf,
3533 stderr);
3534#endif
3535 wxschematron = xmlSchematronParse(ctxt);
3536 if (wxschematron == NULL) {
3537 xmlGenericError(xmlGenericErrorContext,
3538 "Schematron schema %s failed to compile\n", schematron);
3539 progresult = XMLLINT_ERR_SCHEMACOMP;
3540 schematron = NULL;
3541 }
3542 xmlSchematronFreeParserCtxt(ctxt);
3543 if (timing) {
3544 endTimer("Compiling the schemas");
3545 }
3546 }
3547#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00003548#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003549 if ((relaxng != NULL) && (sax == 0)
Daniel Veillard81273902003-09-30 00:43:48 +00003550#ifdef LIBXML_READER_ENABLED
3551 && (stream == 0)
3552#endif /* LIBXML_READER_ENABLED */
3553 ) {
Daniel Veillard71531f32003-02-05 13:19:53 +00003554 xmlRelaxNGParserCtxtPtr ctxt;
3555
Daniel Veillardce192eb2003-04-16 15:58:05 +00003556 /* forces loading the DTDs */
Daniel Veillardf1edb102009-08-10 14:43:18 +02003557 xmlLoadExtDtdDefaultValue |= 1;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003558 options |= XML_PARSE_DTDLOAD;
Daniel Veillard42f12e92003-03-07 18:32:59 +00003559 if (timing) {
3560 startTimer();
3561 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003562 ctxt = xmlRelaxNGNewParserCtxt(relaxng);
3563 xmlRelaxNGSetParserErrors(ctxt,
3564 (xmlRelaxNGValidityErrorFunc) fprintf,
3565 (xmlRelaxNGValidityWarningFunc) fprintf,
3566 stderr);
3567 relaxngschemas = xmlRelaxNGParse(ctxt);
Daniel Veillardce192eb2003-04-16 15:58:05 +00003568 if (relaxngschemas == NULL) {
3569 xmlGenericError(xmlGenericErrorContext,
3570 "Relax-NG schema %s failed to compile\n", relaxng);
William M. Brack8304d872004-06-08 13:29:32 +00003571 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillardce192eb2003-04-16 15:58:05 +00003572 relaxng = NULL;
3573 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003574 xmlRelaxNGFreeParserCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00003575 if (timing) {
3576 endTimer("Compiling the schemas");
3577 }
Daniel Veillardebe25d42004-03-25 09:35:49 +00003578 } else if ((schema != NULL)
3579#ifdef LIBXML_READER_ENABLED
Daniel Veillardf10ae122005-07-10 19:03:16 +00003580 && (stream == 0)
Daniel Veillardebe25d42004-03-25 09:35:49 +00003581#endif
3582 ) {
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003583 xmlSchemaParserCtxtPtr ctxt;
3584
3585 if (timing) {
3586 startTimer();
3587 }
3588 ctxt = xmlSchemaNewParserCtxt(schema);
3589 xmlSchemaSetParserErrors(ctxt,
3590 (xmlSchemaValidityErrorFunc) fprintf,
3591 (xmlSchemaValidityWarningFunc) fprintf,
3592 stderr);
3593 wxschemas = xmlSchemaParse(ctxt);
3594 if (wxschemas == NULL) {
3595 xmlGenericError(xmlGenericErrorContext,
3596 "WXS schema %s failed to compile\n", schema);
William M. Brack8304d872004-06-08 13:29:32 +00003597 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003598 schema = NULL;
3599 }
3600 xmlSchemaFreeParserCtxt(ctxt);
3601 if (timing) {
3602 endTimer("Compiling the schemas");
3603 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003604 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003605#endif /* LIBXML_SCHEMAS_ENABLED */
3606#ifdef LIBXML_PATTERN_ENABLED
Daniel Veillard39e5c892005-07-03 22:48:50 +00003607 if ((pattern != NULL)
Daniel Veillardc9352532005-07-04 14:25:34 +00003608#ifdef LIBXML_READER_ENABLED
Daniel Veillard39e5c892005-07-03 22:48:50 +00003609 && (walker == 0)
3610#endif
3611 ) {
Daniel Veillardffa7b7e2003-12-05 16:10:21 +00003612 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003613 if (patternc == NULL) {
3614 xmlGenericError(xmlGenericErrorContext,
3615 "Pattern %s failed to compile\n", pattern);
William M. Brack8304d872004-06-08 13:29:32 +00003616 progresult = XMLLINT_ERR_SCHEMAPAT;
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003617 pattern = NULL;
3618 }
3619 }
3620#endif /* LIBXML_PATTERN_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003621 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +00003622 if ((!strcmp(argv[i], "-encode")) ||
3623 (!strcmp(argv[i], "--encode"))) {
3624 i++;
3625 continue;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003626 } else if ((!strcmp(argv[i], "-o")) ||
3627 (!strcmp(argv[i], "-output")) ||
3628 (!strcmp(argv[i], "--output"))) {
3629 i++;
3630 continue;
Daniel Veillardbe803962000-06-28 23:40:59 +00003631 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003632#ifdef LIBXML_VALID_ENABLED
Daniel Veillardcd429612000-10-11 15:57:05 +00003633 if ((!strcmp(argv[i], "-dtdvalid")) ||
3634 (!strcmp(argv[i], "--dtdvalid"))) {
3635 i++;
3636 continue;
Daniel Veillardf1edb102009-08-10 14:43:18 +02003637 }
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003638 if ((!strcmp(argv[i], "-path")) ||
3639 (!strcmp(argv[i], "--path"))) {
3640 i++;
3641 continue;
Daniel Veillardcd429612000-10-11 15:57:05 +00003642 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00003643 if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3644 (!strcmp(argv[i], "--dtdvalidfpi"))) {
3645 i++;
3646 continue;
3647 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003648#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard71531f32003-02-05 13:19:53 +00003649 if ((!strcmp(argv[i], "-relaxng")) ||
3650 (!strcmp(argv[i], "--relaxng"))) {
3651 i++;
3652 continue;
3653 }
Daniel Veillard87076042004-05-03 22:54:49 +00003654 if ((!strcmp(argv[i], "-maxmem")) ||
3655 (!strcmp(argv[i], "--maxmem"))) {
3656 i++;
3657 continue;
3658 }
Adam Spraggd2e62312010-11-03 15:33:40 +01003659 if ((!strcmp(argv[i], "-pretty")) ||
3660 (!strcmp(argv[i], "--pretty"))) {
3661 i++;
3662 continue;
3663 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003664 if ((!strcmp(argv[i], "-schema")) ||
3665 (!strcmp(argv[i], "--schema"))) {
3666 i++;
3667 continue;
3668 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00003669 if ((!strcmp(argv[i], "-schematron")) ||
3670 (!strcmp(argv[i], "--schematron"))) {
3671 i++;
3672 continue;
3673 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003674#ifdef LIBXML_PATTERN_ENABLED
3675 if ((!strcmp(argv[i], "-pattern")) ||
3676 (!strcmp(argv[i], "--pattern"))) {
3677 i++;
3678 continue;
3679 }
3680#endif
Daniel Veillard1934b0c2009-10-07 10:25:06 +02003681#ifdef LIBXML_XPATH_ENABLED
3682 if ((!strcmp(argv[i], "-xpath")) ||
3683 (!strcmp(argv[i], "--xpath"))) {
3684 i++;
3685 continue;
3686 }
3687#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00003688 if ((timing) && (repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00003689 startTimer();
Daniel Veillardcbaf3992001-12-31 16:16:02 +00003690 /* Remember file names. "-" means stdin. <sven@zen.org> */
Daniel Veillard4a6845d2001-01-03 13:32:39 +00003691 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003692 if (repeat) {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003693 xmlParserCtxtPtr ctxt = NULL;
3694
3695 for (acount = 0;acount < repeat;acount++) {
Daniel Veillard81273902003-09-30 00:43:48 +00003696#ifdef LIBXML_READER_ENABLED
Daniel Veillard198c1bf2003-10-20 17:07:41 +00003697 if (stream != 0) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00003698 streamFile(argv[i]);
Daniel Veillard198c1bf2003-10-20 17:07:41 +00003699 } else {
Daniel Veillard81273902003-09-30 00:43:48 +00003700#endif /* LIBXML_READER_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003701 if (sax) {
3702 testSAX(argv[i]);
3703 } else {
3704 if (ctxt == NULL)
3705 ctxt = xmlNewParserCtxt();
3706 parseAndPrintFile(argv[i], ctxt);
3707 }
Daniel Veillard81273902003-09-30 00:43:48 +00003708#ifdef LIBXML_READER_ENABLED
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003709 }
Daniel Veillard81273902003-09-30 00:43:48 +00003710#endif /* LIBXML_READER_ENABLED */
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003711 }
3712 if (ctxt != NULL)
3713 xmlFreeParserCtxt(ctxt);
Daniel Veillard7704fb12003-01-03 16:19:51 +00003714 } else {
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003715 nbregister = 0;
3716
Daniel Veillard81273902003-09-30 00:43:48 +00003717#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003718 if (stream != 0)
3719 streamFile(argv[i]);
3720 else
Daniel Veillard81273902003-09-30 00:43:48 +00003721#endif /* LIBXML_READER_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003722 if (sax) {
3723 testSAX(argv[i]);
3724 } else {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003725 parseAndPrintFile(argv[i], NULL);
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003726 }
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003727
3728 if ((chkregister) && (nbregister != 0)) {
3729 fprintf(stderr, "Registration count off: %d\n", nbregister);
William M. Brack8304d872004-06-08 13:29:32 +00003730 progresult = XMLLINT_ERR_RDREGIS;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003731 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00003732 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003733 files ++;
Daniel Veillarda7866932001-12-04 13:14:44 +00003734 if ((timing) && (repeat)) {
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00003735 endTimer("%d iterations", repeat);
Daniel Veillarda7866932001-12-04 13:14:44 +00003736 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00003737 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003738 }
Daniel Veillardf1edb102009-08-10 14:43:18 +02003739 if (generate)
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003740 parseAndPrintFile(NULL, NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003741 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003742 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003743 }
Daniel Veillard845cce42002-01-09 11:51:37 +00003744 if ((files == 0) && (!generate) && (version == 0)) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003745 usage(argv[0]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003746 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00003747#ifdef LIBXML_SCHEMATRON_ENABLED
3748 if (wxschematron != NULL)
3749 xmlSchematronFree(wxschematron);
3750#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00003751#ifdef LIBXML_SCHEMAS_ENABLED
3752 if (relaxngschemas != NULL)
3753 xmlRelaxNGFree(relaxngschemas);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003754 if (wxschemas != NULL)
3755 xmlSchemaFree(wxschemas);
Daniel Veillard71531f32003-02-05 13:19:53 +00003756 xmlRelaxNGCleanupTypes();
3757#endif
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003758#ifdef LIBXML_PATTERN_ENABLED
3759 if (patternc != NULL)
3760 xmlFreePattern(patternc);
3761#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003762 xmlCleanupParser();
3763 xmlMemoryDump();
3764
Daniel Veillardf7cd4812001-02-23 18:44:52 +00003765 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003766}
Daniel Veillard88a172f2000-08-04 18:23:10 +00003767