blob: dbfc5bc9ea9907d7c174a75e8dfb17be8ac9d85d [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 Veillardce8b83b2000-04-05 18:38:42 +0000101
Daniel Veillard3be27512003-01-26 19:49:04 +0000102#ifndef XML_XML_DEFAULT_CATALOG
103#define XML_XML_DEFAULT_CATALOG "file:///etc/xml/catalog"
104#endif
105
William M. Brack8304d872004-06-08 13:29:32 +0000106typedef enum {
107 XMLLINT_RETURN_OK = 0, /* No error */
108 XMLLINT_ERR_UNCLASS, /* Unclassified */
109 XMLLINT_ERR_DTD, /* Error in DTD */
110 XMLLINT_ERR_VALID, /* Validation error */
111 XMLLINT_ERR_RDFILE, /* CtxtReadFile error */
112 XMLLINT_ERR_SCHEMACOMP, /* Schema compilation */
113 XMLLINT_ERR_OUT, /* Error writing output */
114 XMLLINT_ERR_SCHEMAPAT, /* Error in schema pattern */
115 XMLLINT_ERR_RDREGIS, /* Error in Reader registration */
116 XMLLINT_ERR_MEM /* Out of memory error */
117} xmllintReturnCode;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000118#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000119static int shell = 0;
120static int debugent = 0;
121#endif
Daniel Veillard8326e732003-01-07 00:19:07 +0000122static int debug = 0;
Daniel Veillard87076042004-05-03 22:54:49 +0000123static int maxmem = 0;
Daniel Veillard652327a2003-09-29 18:02:38 +0000124#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000125static int copy = 0;
Daniel Veillard652327a2003-09-29 18:02:38 +0000126#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000127static int recovery = 0;
128static int noent = 0;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +0000129static int noblanks = 0;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000130static int noout = 0;
131static int nowrap = 0;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +0000132#ifdef LIBXML_OUTPUT_ENABLED
133static int format = 0;
134static const char *output = NULL;
135static int compress = 0;
136#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard4432df22003-09-28 18:58:27 +0000137#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000138static int valid = 0;
139static int postvalid = 0;
Daniel Veillardcd429612000-10-11 15:57:05 +0000140static char * dtdvalid = NULL;
Daniel Veillard66f68e72003-08-18 16:39:51 +0000141static char * dtdvalidfpi = NULL;
Daniel Veillard4432df22003-09-28 18:58:27 +0000142#endif
Daniel Veillard71531f32003-02-05 13:19:53 +0000143#ifdef LIBXML_SCHEMAS_ENABLED
144static char * relaxng = NULL;
145static xmlRelaxNGPtr relaxngschemas = NULL;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +0000146static char * schema = NULL;
147static xmlSchemaPtr wxschemas = NULL;
Daniel Veillard71531f32003-02-05 13:19:53 +0000148#endif
Daniel Veillard8c6e6532005-09-08 21:39:47 +0000149#ifdef LIBXML_SCHEMATRON_ENABLED
Daniel Veillardd4501d72005-07-24 14:27:16 +0000150static char * schematron = NULL;
151static xmlSchematronPtr wxschematron = NULL;
152#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000153static int repeat = 0;
154static int insert = 0;
Daniel Veillard656ce942004-04-30 23:11:45 +0000155#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000156static int html = 0;
Daniel Veillard42fd4122003-11-04 08:47:48 +0000157static int xmlout = 0;
Daniel Veillard4432df22003-09-28 18:58:27 +0000158#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000159static int htmlout = 0;
Daniel Veillard73b013f2003-09-30 12:36:01 +0000160#ifdef LIBXML_PUSH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000161static int push = 0;
Daniel Veillard73b013f2003-09-30 12:36:01 +0000162#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillard46e370e2000-07-21 20:32:03 +0000163#ifdef HAVE_SYS_MMAN_H
164static int memory = 0;
165#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +0000166static int testIO = 0;
Daniel Veillardbe803962000-06-28 23:40:59 +0000167static char *encoding = NULL;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000168#ifdef LIBXML_XINCLUDE_ENABLED
169static int xinclude = 0;
170#endif
Daniel Veillard48da9102001-08-07 01:10:10 +0000171static int dtdattrs = 0;
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000172static int loaddtd = 0;
William M. Brack8304d872004-06-08 13:29:32 +0000173static xmllintReturnCode progresult = XMLLINT_RETURN_OK;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000174static int timing = 0;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000175static int generate = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000176static int dropdtd = 0;
Daniel Veillarde2940dd2001-08-22 00:06:49 +0000177#ifdef LIBXML_CATALOG_ENABLED
178static int catalogs = 0;
179static int nocatalogs = 0;
180#endif
Daniel Veillard25048d82004-08-14 22:37:54 +0000181#ifdef LIBXML_C14N_ENABLED
182static int canonical = 0;
Aleksey Sanin2650df12005-06-06 17:16:50 +0000183static int exc_canonical = 0;
Daniel Veillard25048d82004-08-14 22:37:54 +0000184#endif
Daniel Veillard81273902003-09-30 00:43:48 +0000185#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +0000186static int stream = 0;
Daniel Veillard7899c5c2003-11-03 12:31:38 +0000187static int walker = 0;
Daniel Veillard81273902003-09-30 00:43:48 +0000188#endif /* LIBXML_READER_ENABLED */
Daniel Veillard8a1b1852003-01-05 22:37:17 +0000189static int chkregister = 0;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +0000190static int nbregister = 0;
Daniel Veillard81273902003-09-30 00:43:48 +0000191#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +0000192static int sax1 = 0;
Daniel Veillard81273902003-09-30 00:43:48 +0000193#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillardb3de70c2003-12-02 22:32:15 +0000194#ifdef LIBXML_PATTERN_ENABLED
195static const char *pattern = NULL;
196static xmlPatternPtr patternc = NULL;
Daniel Veillard2fc6df92005-01-30 18:42:55 +0000197static xmlStreamCtxtPtr patstream = NULL;
Daniel Veillardb3de70c2003-12-02 22:32:15 +0000198#endif
Daniel Veillard8874b942005-08-25 13:19:21 +0000199static int options = XML_PARSE_COMPACT;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000200static int sax = 0;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +0000201
Daniel Veillard87076042004-05-03 22:54:49 +0000202/************************************************************************
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000203 * *
204 * Entity loading control and customization. *
205 * *
206 ************************************************************************/
207#define MAX_PATHS 64
208static xmlChar *paths[MAX_PATHS + 1];
209static int nbpaths = 0;
210static int load_trace = 0;
211
212static
213void parsePath(const xmlChar *path) {
214 const xmlChar *cur;
215
216 if (path == NULL)
217 return;
218 while (*path != 0) {
219 if (nbpaths >= MAX_PATHS) {
220 fprintf(stderr, "MAX_PATHS reached: too many paths\n");
221 return;
222 }
223 cur = path;
224 while ((*cur == ' ') || (*cur == ':'))
225 cur++;
226 path = cur;
227 while ((*cur != 0) && (*cur != ' ') && (*cur != ':'))
228 cur++;
229 if (cur != path) {
230 paths[nbpaths] = xmlStrndup(path, cur - path);
231 if (paths[nbpaths] != NULL)
232 nbpaths++;
233 path = cur;
234 }
235 }
236}
237
Daniel Veillard24505b02005-07-28 23:49:35 +0000238static xmlExternalEntityLoader defaultEntityLoader = NULL;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000239
240static xmlParserInputPtr
241xmllintExternalEntityLoader(const char *URL, const char *ID,
242 xmlParserCtxtPtr ctxt) {
243 xmlParserInputPtr ret;
244 warningSAXFunc warning = NULL;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000245 errorSAXFunc err = NULL;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000246
247 int i;
248 const char *lastsegment = URL;
249 const char *iter = URL;
250
251 if (nbpaths > 0) {
252 while (*iter != 0) {
253 if (*iter == '/')
254 lastsegment = iter + 1;
255 iter++;
256 }
257 }
258
259 if ((ctxt != NULL) && (ctxt->sax != NULL)) {
260 warning = ctxt->sax->warning;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000261 err = ctxt->sax->error;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000262 ctxt->sax->warning = NULL;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000263 ctxt->sax->error = NULL;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000264 }
265
266 if (defaultEntityLoader != NULL) {
267 ret = defaultEntityLoader(URL, ID, ctxt);
268 if (ret != NULL) {
269 if (warning != NULL)
270 ctxt->sax->warning = warning;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000271 if (err != NULL)
272 ctxt->sax->error = err;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000273 if (load_trace) {
274 fprintf \
275 (stderr,
276 "Loaded URL=\"%s\" ID=\"%s\"\n",
277 URL ? URL : "(null)",
278 ID ? ID : "(null)");
279 }
280 return(ret);
281 }
282 }
283 for (i = 0;i < nbpaths;i++) {
284 xmlChar *newURL;
285
286 newURL = xmlStrdup((const xmlChar *) paths[i]);
287 newURL = xmlStrcat(newURL, (const xmlChar *) "/");
288 newURL = xmlStrcat(newURL, (const xmlChar *) lastsegment);
289 if (newURL != NULL) {
290 ret = defaultEntityLoader((const char *)newURL, ID, ctxt);
291 if (ret != NULL) {
292 if (warning != NULL)
293 ctxt->sax->warning = warning;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000294 if (err != NULL)
295 ctxt->sax->error = err;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000296 if (load_trace) {
297 fprintf \
298 (stderr,
299 "Loaded URL=\"%s\" ID=\"%s\"\n",
300 newURL,
301 ID ? ID : "(null)");
302 }
303 xmlFree(newURL);
304 return(ret);
305 }
306 xmlFree(newURL);
307 }
308 }
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000309 if (err != NULL)
310 ctxt->sax->error = err;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000311 if (warning != NULL) {
312 ctxt->sax->warning = warning;
313 if (URL != NULL)
314 warning(ctxt, "failed to load external entity \"%s\"\n", URL);
315 else if (ID != NULL)
316 warning(ctxt, "failed to load external entity \"%s\"\n", ID);
317 }
318 return(NULL);
319}
320/************************************************************************
Daniel Veillard87076042004-05-03 22:54:49 +0000321 * *
322 * Memory allocation consumption debugging *
323 * *
324 ************************************************************************/
325
Daniel Veillard3af3b592004-05-05 19:22:30 +0000326static void
327OOM(void)
328{
Daniel Veillard87076042004-05-03 22:54:49 +0000329 fprintf(stderr, "Ran out of memory needs > %d bytes\n", maxmem);
William M. Brack8304d872004-06-08 13:29:32 +0000330 progresult = XMLLINT_ERR_MEM;
Daniel Veillard87076042004-05-03 22:54:49 +0000331}
332
Daniel Veillard3af3b592004-05-05 19:22:30 +0000333static void
334myFreeFunc(void *mem)
335{
Daniel Veillard87076042004-05-03 22:54:49 +0000336 xmlMemFree(mem);
337}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000338static void *
339myMallocFunc(size_t size)
340{
Daniel Veillard87076042004-05-03 22:54:49 +0000341 void *ret;
342
343 ret = xmlMemMalloc(size);
344 if (ret != NULL) {
345 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000346 OOM();
347 xmlMemFree(ret);
348 return (NULL);
349 }
Daniel Veillard87076042004-05-03 22:54:49 +0000350 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000351 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000352}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000353static void *
354myReallocFunc(void *mem, size_t size)
355{
Daniel Veillard87076042004-05-03 22:54:49 +0000356 void *ret;
357
358 ret = xmlMemRealloc(mem, size);
359 if (ret != NULL) {
360 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000361 OOM();
362 xmlMemFree(ret);
363 return (NULL);
364 }
Daniel Veillard87076042004-05-03 22:54:49 +0000365 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000366 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000367}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000368static char *
369myStrdupFunc(const char *str)
370{
Daniel Veillard87076042004-05-03 22:54:49 +0000371 char *ret;
372
373 ret = xmlMemoryStrdup(str);
374 if (ret != NULL) {
375 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000376 OOM();
377 xmlFree(ret);
378 return (NULL);
379 }
Daniel Veillard87076042004-05-03 22:54:49 +0000380 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000381 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000382}
Daniel Veillard87076042004-05-03 22:54:49 +0000383/************************************************************************
384 * *
385 * Internal timing routines to remove the necessity to have *
386 * unix-specific function calls. *
387 * *
388 ************************************************************************/
Daniel Veillard01db67c2001-12-18 07:09:59 +0000389
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000390#ifndef HAVE_GETTIMEOFDAY
391#ifdef HAVE_SYS_TIMEB_H
392#ifdef HAVE_SYS_TIME_H
393#ifdef HAVE_FTIME
394
Daniel Veillard01c13b52002-12-10 15:19:08 +0000395static int
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000396my_gettimeofday(struct timeval *tvp, void *tzp)
397{
398 struct timeb timebuffer;
399
400 ftime(&timebuffer);
401 if (tvp) {
402 tvp->tv_sec = timebuffer.time;
403 tvp->tv_usec = timebuffer.millitm * 1000L;
404 }
405 return (0);
406}
407#define HAVE_GETTIMEOFDAY 1
408#define gettimeofday my_gettimeofday
409
410#endif /* HAVE_FTIME */
411#endif /* HAVE_SYS_TIME_H */
412#endif /* HAVE_SYS_TIMEB_H */
413#endif /* !HAVE_GETTIMEOFDAY */
414
Daniel Veillard01db67c2001-12-18 07:09:59 +0000415#if defined(HAVE_GETTIMEOFDAY)
416static struct timeval begin, end;
417
418/*
419 * startTimer: call where you want to start timing
420 */
421static void
422startTimer(void)
423{
424 gettimeofday(&begin, NULL);
425}
426
427/*
428 * endTimer: call where you want to stop timing and to print out a
429 * message about the timing performed; format is a printf
430 * type argument
431 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000432static void XMLCDECL
Daniel Veillard118aed72002-09-24 14:13:13 +0000433endTimer(const char *fmt, ...)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000434{
435 long msec;
436 va_list ap;
437
438 gettimeofday(&end, NULL);
439 msec = end.tv_sec - begin.tv_sec;
440 msec *= 1000;
441 msec += (end.tv_usec - begin.tv_usec) / 1000;
442
443#ifndef HAVE_STDARG_H
444#error "endTimer required stdarg functions"
445#endif
Daniel Veillard118aed72002-09-24 14:13:13 +0000446 va_start(ap, fmt);
447 vfprintf(stderr, fmt, ap);
Daniel Veillard01db67c2001-12-18 07:09:59 +0000448 va_end(ap);
449
450 fprintf(stderr, " took %ld ms\n", msec);
451}
452#elif defined(HAVE_TIME_H)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000453/*
454 * No gettimeofday function, so we have to make do with calling clock.
455 * This is obviously less accurate, but there's little we can do about
456 * that.
457 */
Daniel Veillard90bc3712002-03-07 15:12:58 +0000458#ifndef CLOCKS_PER_SEC
459#define CLOCKS_PER_SEC 100
460#endif
Daniel Veillard01db67c2001-12-18 07:09:59 +0000461
462static clock_t begin, end;
463static void
464startTimer(void)
465{
466 begin = clock();
467}
Daniel Veillardffa3c742005-07-21 13:24:09 +0000468static void XMLCDECL
Daniel Veillard01db67c2001-12-18 07:09:59 +0000469endTimer(const char *fmt, ...)
470{
471 long msec;
472 va_list ap;
473
474 end = clock();
475 msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
476
477#ifndef HAVE_STDARG_H
478#error "endTimer required stdarg functions"
479#endif
480 va_start(ap, fmt);
481 vfprintf(stderr, fmt, ap);
482 va_end(ap);
483 fprintf(stderr, " took %ld ms\n", msec);
484}
485#else
486
487/*
488 * We don't have a gettimeofday or time.h, so we just don't do timing
489 */
490static void
491startTimer(void)
492{
493 /*
494 * Do nothing
495 */
496}
Daniel Veillardffa3c742005-07-21 13:24:09 +0000497static void XMLCDECL
Daniel Veillard01db67c2001-12-18 07:09:59 +0000498endTimer(char *format, ...)
499{
500 /*
501 * We cannot do anything because we don't have a timing function
502 */
503#ifdef HAVE_STDARG_H
504 va_start(ap, format);
505 vfprintf(stderr, format, ap);
506 va_end(ap);
507 fprintf(stderr, " was not timed\n", msec);
508#else
509 /* We don't have gettimeofday, time or stdarg.h, what crazy world is
510 * this ?!
511 */
512#endif
513}
514#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000515/************************************************************************
516 * *
517 * HTML ouput *
518 * *
519 ************************************************************************/
Daniel Veillard24505b02005-07-28 23:49:35 +0000520static char buffer[50000];
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000521
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000522static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000523xmlHTMLEncodeSend(void) {
524 char *result;
525
526 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
527 if (result) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000528 xmlGenericError(xmlGenericErrorContext, "%s", result);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000529 xmlFree(result);
530 }
531 buffer[0] = 0;
532}
533
534/**
535 * xmlHTMLPrintFileInfo:
536 * @input: an xmlParserInputPtr input
537 *
538 * Displays the associated file and line informations for the current input
539 */
540
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000541static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000542xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000543 int len;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000544 xmlGenericError(xmlGenericErrorContext, "<p>");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000545
546 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000547 if (input != NULL) {
548 if (input->filename) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000549 snprintf(&buffer[len], sizeof(buffer) - len, "%s:%d: ", input->filename,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000550 input->line);
551 } else {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000552 snprintf(&buffer[len], sizeof(buffer) - len, "Entity: line %d: ", input->line);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000553 }
554 }
555 xmlHTMLEncodeSend();
556}
557
558/**
559 * xmlHTMLPrintFileContext:
560 * @input: an xmlParserInputPtr input
561 *
562 * Displays current context within the input content for error tracking
563 */
564
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000565static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000566xmlHTMLPrintFileContext(xmlParserInputPtr input) {
567 const xmlChar *cur, *base;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000568 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000569 int n;
570
571 if (input == NULL) return;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000572 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000573 cur = input->cur;
574 base = input->base;
575 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
576 cur--;
577 }
578 n = 0;
579 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
580 cur--;
581 if ((*cur == '\n') || (*cur == '\r')) cur++;
582 base = cur;
583 n = 0;
584 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000585 len = strlen(buffer);
586 snprintf(&buffer[len], sizeof(buffer) - len, "%c",
587 (unsigned char) *cur++);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000588 n++;
589 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000590 len = strlen(buffer);
591 snprintf(&buffer[len], sizeof(buffer) - len, "\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000592 cur = input->cur;
593 while ((*cur == '\n') || (*cur == '\r'))
594 cur--;
595 n = 0;
596 while ((cur != base) && (n++ < 80)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000597 len = strlen(buffer);
598 snprintf(&buffer[len], sizeof(buffer) - len, " ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000599 base++;
600 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000601 len = strlen(buffer);
602 snprintf(&buffer[len], sizeof(buffer) - len, "^\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000603 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000604 xmlGenericError(xmlGenericErrorContext, "</pre>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000605}
606
607/**
608 * xmlHTMLError:
609 * @ctx: an XML parser context
610 * @msg: the message to display/transmit
611 * @...: extra parameters for the message display
612 *
613 * Display and format an error messages, gives file, line, position and
614 * extra parameters.
615 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000616static void XMLCDECL
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000617xmlHTMLError(void *ctx, const char *msg, ...)
618{
619 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
620 xmlParserInputPtr input;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000621 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000622 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000623
624 buffer[0] = 0;
625 input = ctxt->input;
626 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000627 input = ctxt->inputTab[ctxt->inputNr - 2];
628 }
629
630 xmlHTMLPrintFileInfo(input);
631
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000632 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000633 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000634 len = strlen(buffer);
635 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000636 va_end(args);
637 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000638 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000639
640 xmlHTMLPrintFileContext(input);
641 xmlHTMLEncodeSend();
642}
643
644/**
645 * xmlHTMLWarning:
646 * @ctx: an XML parser context
647 * @msg: the message to display/transmit
648 * @...: extra parameters for the message display
649 *
650 * Display and format a warning messages, gives file, line, position and
651 * extra parameters.
652 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000653static void XMLCDECL
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000654xmlHTMLWarning(void *ctx, const char *msg, ...)
655{
656 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
657 xmlParserInputPtr input;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000658 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000659 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000660
661 buffer[0] = 0;
662 input = ctxt->input;
663 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000664 input = ctxt->inputTab[ctxt->inputNr - 2];
665 }
666
667
668 xmlHTMLPrintFileInfo(input);
669
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000670 xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000671 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000672 len = strlen(buffer);
673 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000674 va_end(args);
675 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000676 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000677
678 xmlHTMLPrintFileContext(input);
679 xmlHTMLEncodeSend();
680}
681
682/**
683 * xmlHTMLValidityError:
684 * @ctx: an XML parser context
685 * @msg: the message to display/transmit
686 * @...: extra parameters for the message display
687 *
688 * Display and format an validity error messages, gives file,
689 * line, position and extra parameters.
690 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000691static void XMLCDECL
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000692xmlHTMLValidityError(void *ctx, const char *msg, ...)
693{
694 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
695 xmlParserInputPtr input;
696 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000697 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000698
699 buffer[0] = 0;
700 input = ctxt->input;
701 if ((input->filename == NULL) && (ctxt->inputNr > 1))
702 input = ctxt->inputTab[ctxt->inputNr - 2];
703
704 xmlHTMLPrintFileInfo(input);
705
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000706 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000707 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000708 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000709 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000710 va_end(args);
711 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000712 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000713
714 xmlHTMLPrintFileContext(input);
715 xmlHTMLEncodeSend();
Daniel Veillard9fcb4912005-03-16 12:57:31 +0000716 progresult = XMLLINT_ERR_VALID;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000717}
718
719/**
720 * xmlHTMLValidityWarning:
721 * @ctx: an XML parser context
722 * @msg: the message to display/transmit
723 * @...: extra parameters for the message display
724 *
725 * Display and format a validity warning messages, gives file, line,
726 * position and extra parameters.
727 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000728static void XMLCDECL
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000729xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
730{
731 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
732 xmlParserInputPtr input;
733 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000734 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000735
736 buffer[0] = 0;
737 input = ctxt->input;
738 if ((input->filename == NULL) && (ctxt->inputNr > 1))
739 input = ctxt->inputTab[ctxt->inputNr - 2];
740
741 xmlHTMLPrintFileInfo(input);
742
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000743 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000744 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000745 len = strlen(buffer);
746 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000747 va_end(args);
748 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000749 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000750
751 xmlHTMLPrintFileContext(input);
752 xmlHTMLEncodeSend();
753}
754
755/************************************************************************
756 * *
757 * Shell Interface *
758 * *
759 ************************************************************************/
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000760#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000761#ifdef LIBXML_XPATH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000762/**
763 * xmlShellReadline:
764 * @prompt: the prompt value
765 *
766 * Read a string
767 *
768 * Returns a pointer to it or NULL on EOF the caller is expected to
769 * free the returned string.
770 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000771static char *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000772xmlShellReadline(char *prompt) {
773#ifdef HAVE_LIBREADLINE
774 char *line_read;
775
776 /* Get a line from the user. */
777 line_read = readline (prompt);
778
779 /* If the line has any text in it, save it on the history. */
780 if (line_read && *line_read)
781 add_history (line_read);
782
783 return (line_read);
784#else
785 char line_read[501];
Daniel Veillard29e43992001-12-13 22:21:58 +0000786 char *ret;
787 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000788
789 if (prompt != NULL)
790 fprintf(stdout, "%s", prompt);
791 if (!fgets(line_read, 500, stdin))
792 return(NULL);
793 line_read[500] = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000794 len = strlen(line_read);
795 ret = (char *) malloc(len + 1);
796 if (ret != NULL) {
797 memcpy (ret, line_read, len + 1);
798 }
799 return(ret);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000800#endif
801}
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000802#endif /* LIBXML_XPATH_ENABLED */
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000803#endif /* LIBXML_DEBUG_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000804
805/************************************************************************
806 * *
Daniel Veillard5e873c42000-04-12 13:27:38 +0000807 * I/O Interfaces *
808 * *
809 ************************************************************************/
810
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000811static int myRead(FILE *f, char * buf, int len) {
812 return(fread(buf, 1, len, f));
Daniel Veillard5e873c42000-04-12 13:27:38 +0000813}
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000814static void myClose(FILE *f) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000815 if (f != stdin) {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000816 fclose(f);
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000817 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000818}
819
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000820/************************************************************************
821 * *
822 * SAX based tests *
823 * *
824 ************************************************************************/
825
826/*
827 * empty SAX block
828 */
Daniel Veillard24505b02005-07-28 23:49:35 +0000829static xmlSAXHandler emptySAXHandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000830 NULL, /* internalSubset */
831 NULL, /* isStandalone */
832 NULL, /* hasInternalSubset */
833 NULL, /* hasExternalSubset */
834 NULL, /* resolveEntity */
835 NULL, /* getEntity */
836 NULL, /* entityDecl */
837 NULL, /* notationDecl */
838 NULL, /* attributeDecl */
839 NULL, /* elementDecl */
840 NULL, /* unparsedEntityDecl */
841 NULL, /* setDocumentLocator */
842 NULL, /* startDocument */
843 NULL, /* endDocument */
844 NULL, /* startElement */
845 NULL, /* endElement */
846 NULL, /* reference */
847 NULL, /* characters */
848 NULL, /* ignorableWhitespace */
849 NULL, /* processingInstruction */
850 NULL, /* comment */
851 NULL, /* xmlParserWarning */
852 NULL, /* xmlParserError */
853 NULL, /* xmlParserError */
854 NULL, /* getParameterEntity */
855 NULL, /* cdataBlock; */
856 NULL, /* externalSubset; */
Daniel Veillard971771e2005-07-09 17:32:57 +0000857 XML_SAX2_MAGIC,
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000858 NULL,
859 NULL, /* startElementNs */
860 NULL, /* endElementNs */
861 NULL /* xmlStructuredErrorFunc */
862};
863
Daniel Veillard24505b02005-07-28 23:49:35 +0000864static xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000865extern xmlSAXHandlerPtr debugSAXHandler;
866static int callbacks;
867
868/**
869 * isStandaloneDebug:
870 * @ctxt: An XML parser context
871 *
872 * Is this document tagged standalone ?
873 *
874 * Returns 1 if true
875 */
876static int
877isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
878{
879 callbacks++;
880 if (noout)
881 return(0);
882 fprintf(stdout, "SAX.isStandalone()\n");
883 return(0);
884}
885
886/**
887 * hasInternalSubsetDebug:
888 * @ctxt: An XML parser context
889 *
890 * Does this document has an internal subset
891 *
892 * Returns 1 if true
893 */
894static int
895hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
896{
897 callbacks++;
898 if (noout)
899 return(0);
900 fprintf(stdout, "SAX.hasInternalSubset()\n");
901 return(0);
902}
903
904/**
905 * hasExternalSubsetDebug:
906 * @ctxt: An XML parser context
907 *
908 * Does this document has an external subset
909 *
910 * Returns 1 if true
911 */
912static int
913hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
914{
915 callbacks++;
916 if (noout)
917 return(0);
918 fprintf(stdout, "SAX.hasExternalSubset()\n");
919 return(0);
920}
921
922/**
923 * internalSubsetDebug:
924 * @ctxt: An XML parser context
925 *
926 * Does this document has an internal subset
927 */
928static void
929internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
930 const xmlChar *ExternalID, const xmlChar *SystemID)
931{
932 callbacks++;
933 if (noout)
934 return;
935 fprintf(stdout, "SAX.internalSubset(%s,", name);
936 if (ExternalID == NULL)
937 fprintf(stdout, " ,");
938 else
939 fprintf(stdout, " %s,", ExternalID);
940 if (SystemID == NULL)
941 fprintf(stdout, " )\n");
942 else
943 fprintf(stdout, " %s)\n", SystemID);
944}
945
946/**
947 * externalSubsetDebug:
948 * @ctxt: An XML parser context
949 *
950 * Does this document has an external subset
951 */
952static void
953externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
954 const xmlChar *ExternalID, const xmlChar *SystemID)
955{
956 callbacks++;
957 if (noout)
958 return;
959 fprintf(stdout, "SAX.externalSubset(%s,", name);
960 if (ExternalID == NULL)
961 fprintf(stdout, " ,");
962 else
963 fprintf(stdout, " %s,", ExternalID);
964 if (SystemID == NULL)
965 fprintf(stdout, " )\n");
966 else
967 fprintf(stdout, " %s)\n", SystemID);
968}
969
970/**
971 * resolveEntityDebug:
972 * @ctxt: An XML parser context
973 * @publicId: The public ID of the entity
974 * @systemId: The system ID of the entity
975 *
976 * Special entity resolver, better left to the parser, it has
977 * more context than the application layer.
978 * The default behaviour is to NOT resolve the entities, in that case
979 * the ENTITY_REF nodes are built in the structure (and the parameter
980 * values).
981 *
982 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
983 */
984static xmlParserInputPtr
985resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
986{
987 callbacks++;
988 if (noout)
989 return(NULL);
990 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
991
992
993 fprintf(stdout, "SAX.resolveEntity(");
994 if (publicId != NULL)
995 fprintf(stdout, "%s", (char *)publicId);
996 else
997 fprintf(stdout, " ");
998 if (systemId != NULL)
999 fprintf(stdout, ", %s)\n", (char *)systemId);
1000 else
1001 fprintf(stdout, ", )\n");
1002 return(NULL);
1003}
1004
1005/**
1006 * getEntityDebug:
1007 * @ctxt: An XML parser context
1008 * @name: The entity name
1009 *
1010 * Get an entity by name
1011 *
1012 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
1013 */
1014static xmlEntityPtr
1015getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1016{
1017 callbacks++;
1018 if (noout)
1019 return(NULL);
1020 fprintf(stdout, "SAX.getEntity(%s)\n", name);
1021 return(NULL);
1022}
1023
1024/**
1025 * getParameterEntityDebug:
1026 * @ctxt: An XML parser context
1027 * @name: The entity name
1028 *
1029 * Get a parameter entity by name
1030 *
1031 * Returns the xmlParserInputPtr
1032 */
1033static xmlEntityPtr
1034getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1035{
1036 callbacks++;
1037 if (noout)
1038 return(NULL);
1039 fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
1040 return(NULL);
1041}
1042
1043
1044/**
1045 * entityDeclDebug:
1046 * @ctxt: An XML parser context
1047 * @name: the entity name
1048 * @type: the entity type
1049 * @publicId: The public ID of the entity
1050 * @systemId: The system ID of the entity
1051 * @content: the entity value (without processing).
1052 *
1053 * An entity definition has been parsed
1054 */
1055static void
1056entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
1057 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
1058{
1059const xmlChar *nullstr = BAD_CAST "(null)";
1060 /* not all libraries handle printing null pointers nicely */
1061 if (publicId == NULL)
1062 publicId = nullstr;
1063 if (systemId == NULL)
1064 systemId = nullstr;
1065 if (content == NULL)
1066 content = (xmlChar *)nullstr;
1067 callbacks++;
1068 if (noout)
1069 return;
1070 fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
1071 name, type, publicId, systemId, content);
1072}
1073
1074/**
1075 * attributeDeclDebug:
1076 * @ctxt: An XML parser context
1077 * @name: the attribute name
1078 * @type: the attribute type
1079 *
1080 * An attribute definition has been parsed
1081 */
1082static void
1083attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar * elem,
1084 const xmlChar * name, int type, int def,
1085 const xmlChar * defaultValue, xmlEnumerationPtr tree)
1086{
1087 callbacks++;
1088 if (noout)
1089 return;
1090 if (defaultValue == NULL)
1091 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
1092 elem, name, type, def);
1093 else
1094 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
1095 elem, name, type, def, defaultValue);
1096 xmlFreeEnumeration(tree);
1097}
1098
1099/**
1100 * elementDeclDebug:
1101 * @ctxt: An XML parser context
1102 * @name: the element name
1103 * @type: the element type
1104 * @content: the element value (without processing).
1105 *
1106 * An element definition has been parsed
1107 */
1108static void
1109elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
1110 xmlElementContentPtr content ATTRIBUTE_UNUSED)
1111{
1112 callbacks++;
1113 if (noout)
1114 return;
1115 fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
1116 name, type);
1117}
1118
1119/**
1120 * notationDeclDebug:
1121 * @ctxt: An XML parser context
1122 * @name: The name of the notation
1123 * @publicId: The public ID of the entity
1124 * @systemId: The system ID of the entity
1125 *
1126 * What to do when a notation declaration has been parsed.
1127 */
1128static void
1129notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
1130 const xmlChar *publicId, const xmlChar *systemId)
1131{
1132 callbacks++;
1133 if (noout)
1134 return;
1135 fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
1136 (char *) name, (char *) publicId, (char *) systemId);
1137}
1138
1139/**
1140 * unparsedEntityDeclDebug:
1141 * @ctxt: An XML parser context
1142 * @name: The name of the entity
1143 * @publicId: The public ID of the entity
1144 * @systemId: The system ID of the entity
1145 * @notationName: the name of the notation
1146 *
1147 * What to do when an unparsed entity declaration is parsed
1148 */
1149static void
1150unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
1151 const xmlChar *publicId, const xmlChar *systemId,
1152 const xmlChar *notationName)
1153{
1154const xmlChar *nullstr = BAD_CAST "(null)";
1155
1156 if (publicId == NULL)
1157 publicId = nullstr;
1158 if (systemId == NULL)
1159 systemId = nullstr;
1160 if (notationName == NULL)
1161 notationName = nullstr;
1162 callbacks++;
1163 if (noout)
1164 return;
1165 fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
1166 (char *) name, (char *) publicId, (char *) systemId,
1167 (char *) notationName);
1168}
1169
1170/**
1171 * setDocumentLocatorDebug:
1172 * @ctxt: An XML parser context
1173 * @loc: A SAX Locator
1174 *
1175 * Receive the document locator at startup, actually xmlDefaultSAXLocator
1176 * Everything is available on the context, so this is useless in our case.
1177 */
1178static void
1179setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
1180{
1181 callbacks++;
1182 if (noout)
1183 return;
1184 fprintf(stdout, "SAX.setDocumentLocator()\n");
1185}
1186
1187/**
1188 * startDocumentDebug:
1189 * @ctxt: An XML parser context
1190 *
1191 * called when the document start being processed.
1192 */
1193static void
1194startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
1195{
1196 callbacks++;
1197 if (noout)
1198 return;
1199 fprintf(stdout, "SAX.startDocument()\n");
1200}
1201
1202/**
1203 * endDocumentDebug:
1204 * @ctxt: An XML parser context
1205 *
1206 * called when the document end has been detected.
1207 */
1208static void
1209endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
1210{
1211 callbacks++;
1212 if (noout)
1213 return;
1214 fprintf(stdout, "SAX.endDocument()\n");
1215}
1216
1217/**
1218 * startElementDebug:
1219 * @ctxt: An XML parser context
1220 * @name: The element name
1221 *
1222 * called when an opening tag has been processed.
1223 */
1224static void
1225startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
1226{
1227 int i;
1228
1229 callbacks++;
1230 if (noout)
1231 return;
1232 fprintf(stdout, "SAX.startElement(%s", (char *) name);
1233 if (atts != NULL) {
1234 for (i = 0;(atts[i] != NULL);i++) {
1235 fprintf(stdout, ", %s='", atts[i++]);
1236 if (atts[i] != NULL)
1237 fprintf(stdout, "%s'", atts[i]);
1238 }
1239 }
1240 fprintf(stdout, ")\n");
1241}
1242
1243/**
1244 * endElementDebug:
1245 * @ctxt: An XML parser context
1246 * @name: The element name
1247 *
1248 * called when the end of an element has been detected.
1249 */
1250static void
1251endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1252{
1253 callbacks++;
1254 if (noout)
1255 return;
1256 fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
1257}
1258
1259/**
1260 * charactersDebug:
1261 * @ctxt: An XML parser context
1262 * @ch: a xmlChar string
1263 * @len: the number of xmlChar
1264 *
1265 * receiving some chars from the parser.
1266 * Question: how much at a time ???
1267 */
1268static void
1269charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
1270{
1271 char out[40];
1272 int i;
1273
1274 callbacks++;
1275 if (noout)
1276 return;
1277 for (i = 0;(i<len) && (i < 30);i++)
1278 out[i] = ch[i];
1279 out[i] = 0;
1280
1281 fprintf(stdout, "SAX.characters(%s, %d)\n", out, len);
1282}
1283
1284/**
1285 * referenceDebug:
1286 * @ctxt: An XML parser context
1287 * @name: The entity name
1288 *
1289 * called when an entity reference is detected.
1290 */
1291static void
1292referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1293{
1294 callbacks++;
1295 if (noout)
1296 return;
1297 fprintf(stdout, "SAX.reference(%s)\n", name);
1298}
1299
1300/**
1301 * ignorableWhitespaceDebug:
1302 * @ctxt: An XML parser context
1303 * @ch: a xmlChar string
1304 * @start: the first char in the string
1305 * @len: the number of xmlChar
1306 *
1307 * receiving some ignorable whitespaces from the parser.
1308 * Question: how much at a time ???
1309 */
1310static void
1311ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
1312{
1313 char out[40];
1314 int i;
1315
1316 callbacks++;
1317 if (noout)
1318 return;
1319 for (i = 0;(i<len) && (i < 30);i++)
1320 out[i] = ch[i];
1321 out[i] = 0;
1322 fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", out, len);
1323}
1324
1325/**
1326 * processingInstructionDebug:
1327 * @ctxt: An XML parser context
1328 * @target: the target name
1329 * @data: the PI data's
1330 * @len: the number of xmlChar
1331 *
1332 * A processing instruction has been parsed.
1333 */
1334static void
1335processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
1336 const xmlChar *data)
1337{
1338 callbacks++;
1339 if (noout)
1340 return;
1341 if (data != NULL)
1342 fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
1343 (char *) target, (char *) data);
1344 else
1345 fprintf(stdout, "SAX.processingInstruction(%s, NULL)\n",
1346 (char *) target);
1347}
1348
1349/**
1350 * cdataBlockDebug:
1351 * @ctx: the user data (XML parser context)
1352 * @value: The pcdata content
1353 * @len: the block length
1354 *
1355 * called when a pcdata block has been parsed
1356 */
1357static void
1358cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
1359{
1360 callbacks++;
1361 if (noout)
1362 return;
1363 fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
1364 (char *) value, len);
1365}
1366
1367/**
1368 * commentDebug:
1369 * @ctxt: An XML parser context
1370 * @value: the comment content
1371 *
1372 * A comment has been parsed.
1373 */
1374static void
1375commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
1376{
1377 callbacks++;
1378 if (noout)
1379 return;
1380 fprintf(stdout, "SAX.comment(%s)\n", value);
1381}
1382
1383/**
1384 * warningDebug:
1385 * @ctxt: An XML parser context
1386 * @msg: the message to display/transmit
1387 * @...: extra parameters for the message display
1388 *
1389 * Display and format a warning messages, gives file, line, position and
1390 * extra parameters.
1391 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001392static void XMLCDECL
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001393warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1394{
1395 va_list args;
1396
1397 callbacks++;
1398 if (noout)
1399 return;
1400 va_start(args, msg);
1401 fprintf(stdout, "SAX.warning: ");
1402 vfprintf(stdout, msg, args);
1403 va_end(args);
1404}
1405
1406/**
1407 * errorDebug:
1408 * @ctxt: An XML parser context
1409 * @msg: the message to display/transmit
1410 * @...: extra parameters for the message display
1411 *
1412 * Display and format a error messages, gives file, line, position and
1413 * extra parameters.
1414 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001415static void XMLCDECL
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001416errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1417{
1418 va_list args;
1419
1420 callbacks++;
1421 if (noout)
1422 return;
1423 va_start(args, msg);
1424 fprintf(stdout, "SAX.error: ");
1425 vfprintf(stdout, msg, args);
1426 va_end(args);
1427}
1428
1429/**
1430 * fatalErrorDebug:
1431 * @ctxt: An XML parser context
1432 * @msg: the message to display/transmit
1433 * @...: extra parameters for the message display
1434 *
1435 * Display and format a fatalError messages, gives file, line, position and
1436 * extra parameters.
1437 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001438static void XMLCDECL
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001439fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1440{
1441 va_list args;
1442
1443 callbacks++;
1444 if (noout)
1445 return;
1446 va_start(args, msg);
1447 fprintf(stdout, "SAX.fatalError: ");
1448 vfprintf(stdout, msg, args);
1449 va_end(args);
1450}
1451
Daniel Veillard24505b02005-07-28 23:49:35 +00001452static xmlSAXHandler debugSAXHandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001453 internalSubsetDebug,
1454 isStandaloneDebug,
1455 hasInternalSubsetDebug,
1456 hasExternalSubsetDebug,
1457 resolveEntityDebug,
1458 getEntityDebug,
1459 entityDeclDebug,
1460 notationDeclDebug,
1461 attributeDeclDebug,
1462 elementDeclDebug,
1463 unparsedEntityDeclDebug,
1464 setDocumentLocatorDebug,
1465 startDocumentDebug,
1466 endDocumentDebug,
1467 startElementDebug,
1468 endElementDebug,
1469 referenceDebug,
1470 charactersDebug,
1471 ignorableWhitespaceDebug,
1472 processingInstructionDebug,
1473 commentDebug,
1474 warningDebug,
1475 errorDebug,
1476 fatalErrorDebug,
1477 getParameterEntityDebug,
1478 cdataBlockDebug,
1479 externalSubsetDebug,
1480 1,
1481 NULL,
1482 NULL,
1483 NULL,
1484 NULL
1485};
1486
1487xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
1488
1489/*
1490 * SAX2 specific callbacks
1491 */
1492/**
1493 * startElementNsDebug:
1494 * @ctxt: An XML parser context
1495 * @name: The element name
1496 *
1497 * called when an opening tag has been processed.
1498 */
1499static void
1500startElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
1501 const xmlChar *localname,
1502 const xmlChar *prefix,
1503 const xmlChar *URI,
1504 int nb_namespaces,
1505 const xmlChar **namespaces,
1506 int nb_attributes,
1507 int nb_defaulted,
1508 const xmlChar **attributes)
1509{
1510 int i;
1511
1512 callbacks++;
1513 if (noout)
1514 return;
1515 fprintf(stdout, "SAX.startElementNs(%s", (char *) localname);
1516 if (prefix == NULL)
1517 fprintf(stdout, ", NULL");
1518 else
1519 fprintf(stdout, ", %s", (char *) prefix);
1520 if (URI == NULL)
1521 fprintf(stdout, ", NULL");
1522 else
1523 fprintf(stdout, ", '%s'", (char *) URI);
1524 fprintf(stdout, ", %d", nb_namespaces);
1525
1526 if (namespaces != NULL) {
1527 for (i = 0;i < nb_namespaces * 2;i++) {
1528 fprintf(stdout, ", xmlns");
1529 if (namespaces[i] != NULL)
1530 fprintf(stdout, ":%s", namespaces[i]);
1531 i++;
1532 fprintf(stdout, "='%s'", namespaces[i]);
1533 }
1534 }
1535 fprintf(stdout, ", %d, %d", nb_attributes, nb_defaulted);
1536 if (attributes != NULL) {
1537 for (i = 0;i < nb_attributes * 5;i += 5) {
1538 if (attributes[i + 1] != NULL)
1539 fprintf(stdout, ", %s:%s='", attributes[i + 1], attributes[i]);
1540 else
1541 fprintf(stdout, ", %s='", attributes[i]);
1542 fprintf(stdout, "%.4s...', %d", attributes[i + 3],
1543 (int)(attributes[i + 4] - attributes[i + 3]));
1544 }
1545 }
1546 fprintf(stdout, ")\n");
1547}
1548
1549/**
1550 * endElementDebug:
1551 * @ctxt: An XML parser context
1552 * @name: The element name
1553 *
1554 * called when the end of an element has been detected.
1555 */
1556static void
1557endElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
1558 const xmlChar *localname,
1559 const xmlChar *prefix,
1560 const xmlChar *URI)
1561{
1562 callbacks++;
1563 if (noout)
1564 return;
1565 fprintf(stdout, "SAX.endElementNs(%s", (char *) localname);
1566 if (prefix == NULL)
1567 fprintf(stdout, ", NULL");
1568 else
1569 fprintf(stdout, ", %s", (char *) prefix);
1570 if (URI == NULL)
1571 fprintf(stdout, ", NULL)\n");
1572 else
1573 fprintf(stdout, ", '%s')\n", (char *) URI);
1574}
1575
Daniel Veillard24505b02005-07-28 23:49:35 +00001576static xmlSAXHandler debugSAX2HandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001577 internalSubsetDebug,
1578 isStandaloneDebug,
1579 hasInternalSubsetDebug,
1580 hasExternalSubsetDebug,
1581 resolveEntityDebug,
1582 getEntityDebug,
1583 entityDeclDebug,
1584 notationDeclDebug,
1585 attributeDeclDebug,
1586 elementDeclDebug,
1587 unparsedEntityDeclDebug,
1588 setDocumentLocatorDebug,
1589 startDocumentDebug,
1590 endDocumentDebug,
1591 NULL,
1592 NULL,
1593 referenceDebug,
1594 charactersDebug,
1595 ignorableWhitespaceDebug,
1596 processingInstructionDebug,
1597 commentDebug,
1598 warningDebug,
1599 errorDebug,
1600 fatalErrorDebug,
1601 getParameterEntityDebug,
1602 cdataBlockDebug,
1603 externalSubsetDebug,
1604 XML_SAX2_MAGIC,
1605 NULL,
1606 startElementNsDebug,
1607 endElementNsDebug,
1608 NULL
1609};
1610
Daniel Veillard24505b02005-07-28 23:49:35 +00001611static xmlSAXHandlerPtr debugSAX2Handler = &debugSAX2HandlerStruct;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001612
1613static void
1614testSAX(const char *filename) {
1615 xmlSAXHandlerPtr handler;
1616 const char *user_data = "user_data"; /* mostly for debugging */
1617 xmlParserInputBufferPtr buf = NULL;
1618 xmlParserInputPtr inputStream;
1619 xmlParserCtxtPtr ctxt = NULL;
1620 xmlSAXHandlerPtr old_sax = NULL;
1621
1622 callbacks = 0;
1623
1624 if (noout) {
1625 handler = emptySAXHandler;
Daniel Veillard78dfc9f2005-07-10 22:30:30 +00001626#ifdef LIBXML_SAX1_ENABLED
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001627 } else if (sax1) {
1628 handler = debugSAXHandler;
Daniel Veillard78dfc9f2005-07-10 22:30:30 +00001629#endif
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001630 } else {
1631 handler = debugSAX2Handler;
1632 }
1633
1634 /*
1635 * it's not the simplest code but the most generic in term of I/O
1636 */
1637 buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
1638 if (buf == NULL) {
1639 goto error;
1640 }
1641
1642#ifdef LIBXML_SCHEMAS_ENABLED
1643 if (wxschemas != NULL) {
1644 int ret;
1645 xmlSchemaValidCtxtPtr vctxt;
1646
1647 vctxt = xmlSchemaNewValidCtxt(wxschemas);
1648 xmlSchemaSetValidErrors(vctxt,
1649 (xmlSchemaValidityErrorFunc) fprintf,
1650 (xmlSchemaValidityWarningFunc) fprintf,
1651 stderr);
1652
Daniel Veillard971771e2005-07-09 17:32:57 +00001653 ret = xmlSchemaValidateStream(vctxt, buf, 0, handler,
1654 (void *)user_data);
1655 if (repeat == 0) {
1656 if (ret == 0) {
1657 fprintf(stderr, "%s validates\n", filename);
1658 } else if (ret > 0) {
1659 fprintf(stderr, "%s fails to validate\n", filename);
1660 progresult = XMLLINT_ERR_VALID;
1661 } else {
1662 fprintf(stderr, "%s validation generated an internal error\n",
1663 filename);
1664 progresult = XMLLINT_ERR_VALID;
1665 }
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001666 }
1667 xmlSchemaFreeValidCtxt(vctxt);
1668 } else
1669#endif
1670 {
1671 /*
1672 * Create the parser context amd hook the input
1673 */
1674 ctxt = xmlNewParserCtxt();
1675 if (ctxt == NULL) {
1676 xmlFreeParserInputBuffer(buf);
1677 goto error;
1678 }
1679 old_sax = ctxt->sax;
1680 ctxt->sax = handler;
1681 ctxt->userData = (void *) user_data;
1682 inputStream = xmlNewIOInputStream(ctxt, buf, XML_CHAR_ENCODING_NONE);
1683 if (inputStream == NULL) {
1684 xmlFreeParserInputBuffer(buf);
1685 goto error;
1686 }
1687 inputPush(ctxt, inputStream);
1688
1689 /* do the parsing */
1690 xmlParseDocument(ctxt);
1691
1692 if (ctxt->myDoc != NULL) {
1693 fprintf(stderr, "SAX generated a doc !\n");
1694 xmlFreeDoc(ctxt->myDoc);
1695 ctxt->myDoc = NULL;
1696 }
1697 }
1698
1699error:
1700 if (ctxt != NULL) {
1701 ctxt->sax = old_sax;
1702 xmlFreeParserCtxt(ctxt);
1703 }
1704}
1705
Daniel Veillard5e873c42000-04-12 13:27:38 +00001706/************************************************************************
1707 * *
Daniel Veillard7704fb12003-01-03 16:19:51 +00001708 * Stream Test processing *
1709 * *
1710 ************************************************************************/
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001711#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00001712static void processNode(xmlTextReaderPtr reader) {
Daniel Veillard198c1bf2003-10-20 17:07:41 +00001713 const xmlChar *name, *value;
Daniel Veillard16ef8002005-01-31 00:27:50 +00001714 int type, empty;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001715
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001716 type = xmlTextReaderNodeType(reader);
Daniel Veillard16ef8002005-01-31 00:27:50 +00001717 empty = xmlTextReaderIsEmptyElement(reader);
Daniel Veillard99737f52003-03-22 14:55:50 +00001718
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001719 if (debug) {
1720 name = xmlTextReaderConstName(reader);
1721 if (name == NULL)
1722 name = BAD_CAST "--";
Daniel Veillard7704fb12003-01-03 16:19:51 +00001723
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001724 value = xmlTextReaderConstValue(reader);
1725
1726
1727 printf("%d %d %s %d %d",
1728 xmlTextReaderDepth(reader),
1729 type,
1730 name,
Daniel Veillard16ef8002005-01-31 00:27:50 +00001731 empty,
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001732 xmlTextReaderHasValue(reader));
1733 if (value == NULL)
1734 printf("\n");
1735 else {
1736 printf(" %s\n", value);
1737 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001738 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001739#ifdef LIBXML_PATTERN_ENABLED
1740 if (patternc) {
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001741 xmlChar *path = NULL;
1742 int match = -1;
1743
1744 if (type == XML_READER_TYPE_ELEMENT) {
1745 /* do the check only on element start */
1746 match = xmlPatternMatch(patternc, xmlTextReaderCurrentNode(reader));
1747
1748 if (match) {
1749 path = xmlGetNodePath(xmlTextReaderCurrentNode(reader));
1750 printf("Node %s matches pattern %s\n", path, pattern);
1751 }
1752 }
1753 if (patstream != NULL) {
1754 int ret;
1755
1756 if (type == XML_READER_TYPE_ELEMENT) {
1757 ret = xmlStreamPush(patstream,
1758 xmlTextReaderConstLocalName(reader),
1759 xmlTextReaderConstNamespaceUri(reader));
1760 if (ret < 0) {
1761 fprintf(stderr, "xmlStreamPush() failure\n");
1762 xmlFreeStreamCtxt(patstream);
1763 patstream = NULL;
1764 } else if (ret != match) {
1765 if (path == NULL) {
1766 path = xmlGetNodePath(
1767 xmlTextReaderCurrentNode(reader));
1768 }
1769 fprintf(stderr,
1770 "xmlPatternMatch and xmlStreamPush disagree\n");
1771 fprintf(stderr,
1772 " pattern %s node %s\n",
1773 pattern, path);
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001774 }
1775
1776
Daniel Veillard16ef8002005-01-31 00:27:50 +00001777 }
1778 if ((type == XML_READER_TYPE_END_ELEMENT) ||
1779 ((type == XML_READER_TYPE_ELEMENT) && (empty))) {
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001780 ret = xmlStreamPop(patstream);
1781 if (ret < 0) {
1782 fprintf(stderr, "xmlStreamPop() failure\n");
1783 xmlFreeStreamCtxt(patstream);
1784 patstream = NULL;
1785 }
1786 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001787 }
Daniel Veillardf9d16912005-01-30 22:36:30 +00001788 if (path != NULL)
1789 xmlFree(path);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001790 }
1791#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001792}
1793
1794static void streamFile(char *filename) {
1795 xmlTextReaderPtr reader;
1796 int ret;
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001797#ifdef HAVE_SYS_MMAN_H
1798 int fd = -1;
1799 struct stat info;
1800 const char *base = NULL;
1801 xmlParserInputBufferPtr input = NULL;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001802
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001803 if (memory) {
1804 if (stat(filename, &info) < 0)
1805 return;
1806 if ((fd = open(filename, O_RDONLY)) < 0)
1807 return;
1808 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
1809 if (base == (void *) MAP_FAILED)
1810 return;
1811
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001812 reader = xmlReaderForMemory(base, info.st_size, filename,
1813 NULL, options);
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001814 } else
1815#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001816 reader = xmlReaderForFile(filename, NULL, options);
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001817#ifdef LIBXML_PATTERN_ENABLED
Daniel Veillardd4301ab2005-02-03 22:24:10 +00001818 if (pattern != NULL) {
1819 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
1820 if (patternc == NULL) {
1821 xmlGenericError(xmlGenericErrorContext,
1822 "Pattern %s failed to compile\n", pattern);
1823 progresult = XMLLINT_ERR_SCHEMAPAT;
1824 pattern = NULL;
1825 }
1826 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001827 if (patternc != NULL) {
1828 patstream = xmlPatternGetStreamCtxt(patternc);
1829 if (patstream != NULL) {
1830 ret = xmlStreamPush(patstream, NULL, NULL);
1831 if (ret < 0) {
1832 fprintf(stderr, "xmlStreamPush() failure\n");
1833 xmlFreeStreamCtxt(patstream);
1834 patstream = NULL;
1835 }
1836 }
1837 }
1838#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001839
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001840
Daniel Veillard7704fb12003-01-03 16:19:51 +00001841 if (reader != NULL) {
Daniel Veillard4432df22003-09-28 18:58:27 +00001842#ifdef LIBXML_VALID_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00001843 if (valid)
1844 xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
Daniel Veillardce192eb2003-04-16 15:58:05 +00001845 else
Daniel Veillard4432df22003-09-28 18:58:27 +00001846#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardce192eb2003-04-16 15:58:05 +00001847 xmlTextReaderSetParserProp(reader, XML_PARSER_LOADDTD, 1);
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001848#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +00001849 if (relaxng != NULL) {
Daniel Veillard81514ba2003-09-16 23:17:26 +00001850 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001851 startTimer();
1852 }
1853 ret = xmlTextReaderRelaxNGValidate(reader, relaxng);
1854 if (ret < 0) {
1855 xmlGenericError(xmlGenericErrorContext,
1856 "Relax-NG schema %s failed to compile\n", relaxng);
William M. Brack8304d872004-06-08 13:29:32 +00001857 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillardce192eb2003-04-16 15:58:05 +00001858 relaxng = NULL;
1859 }
Daniel Veillard81514ba2003-09-16 23:17:26 +00001860 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001861 endTimer("Compiling the schemas");
1862 }
1863 }
Daniel Veillardf10ae122005-07-10 19:03:16 +00001864 if (schema != NULL) {
1865 if ((timing) && (!repeat)) {
1866 startTimer();
1867 }
1868 ret = xmlTextReaderSchemaValidate(reader, schema);
1869 if (ret < 0) {
1870 xmlGenericError(xmlGenericErrorContext,
1871 "XSD schema %s failed to compile\n", schema);
1872 progresult = XMLLINT_ERR_SCHEMACOMP;
1873 schema = NULL;
1874 }
1875 if ((timing) && (!repeat)) {
1876 endTimer("Compiling the schemas");
1877 }
1878 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001879#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001880
1881 /*
1882 * Process all nodes in sequence
1883 */
Daniel Veillard81514ba2003-09-16 23:17:26 +00001884 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001885 startTimer();
1886 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001887 ret = xmlTextReaderRead(reader);
1888 while (ret == 1) {
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001889 if ((debug)
1890#ifdef LIBXML_PATTERN_ENABLED
1891 || (patternc)
1892#endif
1893 )
Daniel Veillard7704fb12003-01-03 16:19:51 +00001894 processNode(reader);
1895 ret = xmlTextReaderRead(reader);
1896 }
Daniel Veillard81514ba2003-09-16 23:17:26 +00001897 if ((timing) && (!repeat)) {
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001898#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf54cd532004-02-25 11:52:31 +00001899 if (relaxng != NULL)
Daniel Veillard49138f12004-02-19 12:58:36 +00001900 endTimer("Parsing and validating");
1901 else
Daniel Veillardf54cd532004-02-25 11:52:31 +00001902#endif
Daniel Veillard4432df22003-09-28 18:58:27 +00001903#ifdef LIBXML_VALID_ENABLED
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001904 if (valid)
Daniel Veillardce192eb2003-04-16 15:58:05 +00001905 endTimer("Parsing and validating");
1906 else
Daniel Veillard4432df22003-09-28 18:58:27 +00001907#endif
Daniel Veillardf54cd532004-02-25 11:52:31 +00001908 endTimer("Parsing");
Daniel Veillardce192eb2003-04-16 15:58:05 +00001909 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001910
Daniel Veillard4432df22003-09-28 18:58:27 +00001911#ifdef LIBXML_VALID_ENABLED
Daniel Veillardf6bad792003-04-11 19:38:54 +00001912 if (valid) {
1913 if (xmlTextReaderIsValid(reader) != 1) {
1914 xmlGenericError(xmlGenericErrorContext,
1915 "Document %s does not validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001916 progresult = XMLLINT_ERR_VALID;
Daniel Veillardf6bad792003-04-11 19:38:54 +00001917 }
1918 }
Daniel Veillard4432df22003-09-28 18:58:27 +00001919#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001920#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf10ae122005-07-10 19:03:16 +00001921 if ((relaxng != NULL) || (schema != NULL)) {
Daniel Veillardf4e55762003-04-15 23:32:22 +00001922 if (xmlTextReaderIsValid(reader) != 1) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001923 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001924 progresult = XMLLINT_ERR_VALID;
Daniel Veillardf4e55762003-04-15 23:32:22 +00001925 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001926 fprintf(stderr, "%s validates\n", filename);
Daniel Veillardf4e55762003-04-15 23:32:22 +00001927 }
1928 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001929#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001930 /*
1931 * Done, cleanup and status
1932 */
1933 xmlFreeTextReader(reader);
1934 if (ret != 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001935 fprintf(stderr, "%s : failed to parse\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001936 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001937 }
1938 } else {
1939 fprintf(stderr, "Unable to open %s\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001940 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001941 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001942#ifdef LIBXML_PATTERN_ENABLED
1943 if (patstream != NULL) {
1944 xmlFreeStreamCtxt(patstream);
1945 patstream = NULL;
1946 }
1947#endif
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001948#ifdef HAVE_SYS_MMAN_H
1949 if (memory) {
1950 xmlFreeParserInputBuffer(input);
1951 munmap((char *) base, info.st_size);
1952 close(fd);
1953 }
1954#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001955}
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001956
1957static void walkDoc(xmlDocPtr doc) {
1958 xmlTextReaderPtr reader;
1959 int ret;
1960
Daniel Veillardd4301ab2005-02-03 22:24:10 +00001961#ifdef LIBXML_PATTERN_ENABLED
1962 xmlNodePtr root;
1963 const xmlChar *namespaces[22];
1964 int i;
1965 xmlNsPtr ns;
1966
1967 root = xmlDocGetRootElement(doc);
1968 for (ns = root->nsDef, i = 0;ns != NULL && i < 20;ns=ns->next) {
1969 namespaces[i++] = ns->href;
1970 namespaces[i++] = ns->prefix;
1971 }
1972 namespaces[i++] = NULL;
1973 namespaces[i++] = NULL;
1974
1975 if (pattern != NULL) {
1976 patternc = xmlPatterncompile((const xmlChar *) pattern, doc->dict,
1977 0, &namespaces[0]);
1978 if (patternc == NULL) {
1979 xmlGenericError(xmlGenericErrorContext,
1980 "Pattern %s failed to compile\n", pattern);
1981 progresult = XMLLINT_ERR_SCHEMAPAT;
1982 pattern = NULL;
1983 }
1984 }
Daniel Veillard2b2e02d2005-02-05 23:20:22 +00001985 if (patternc != NULL) {
1986 patstream = xmlPatternGetStreamCtxt(patternc);
1987 if (patstream != NULL) {
1988 ret = xmlStreamPush(patstream, NULL, NULL);
1989 if (ret < 0) {
1990 fprintf(stderr, "xmlStreamPush() failure\n");
1991 xmlFreeStreamCtxt(patstream);
1992 patstream = NULL;
1993 }
1994 }
1995 }
Daniel Veillardd4301ab2005-02-03 22:24:10 +00001996#endif /* LIBXML_PATTERN_ENABLED */
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001997 reader = xmlReaderWalker(doc);
1998 if (reader != NULL) {
1999 if ((timing) && (!repeat)) {
2000 startTimer();
2001 }
2002 ret = xmlTextReaderRead(reader);
2003 while (ret == 1) {
Daniel Veillardb3de70c2003-12-02 22:32:15 +00002004 if ((debug)
2005#ifdef LIBXML_PATTERN_ENABLED
2006 || (patternc)
2007#endif
2008 )
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002009 processNode(reader);
2010 ret = xmlTextReaderRead(reader);
2011 }
2012 if ((timing) && (!repeat)) {
2013 endTimer("walking through the doc");
2014 }
2015 xmlFreeTextReader(reader);
2016 if (ret != 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002017 fprintf(stderr, "failed to walk through the doc\n");
William M. Brack8304d872004-06-08 13:29:32 +00002018 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002019 }
2020 } else {
2021 fprintf(stderr, "Failed to crate a reader from the document\n");
William M. Brack8304d872004-06-08 13:29:32 +00002022 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002023 }
Daniel Veillard2b2e02d2005-02-05 23:20:22 +00002024#ifdef LIBXML_PATTERN_ENABLED
2025 if (patstream != NULL) {
2026 xmlFreeStreamCtxt(patstream);
2027 patstream = NULL;
2028 }
2029#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002030}
Daniel Veillard81273902003-09-30 00:43:48 +00002031#endif /* LIBXML_READER_ENABLED */
Daniel Veillard7704fb12003-01-03 16:19:51 +00002032
2033/************************************************************************
2034 * *
2035 * Tree Test processing *
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002036 * *
2037 ************************************************************************/
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002038static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
Daniel Veillard652327a2003-09-29 18:02:38 +00002039 xmlDocPtr doc = NULL;
2040#ifdef LIBXML_TREE_ENABLED
2041 xmlDocPtr tmp;
2042#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002043
Daniel Veillard48b2f892001-02-25 16:11:03 +00002044 if ((timing) && (!repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00002045 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002046
2047
Daniel Veillard652327a2003-09-29 18:02:38 +00002048#ifdef LIBXML_TREE_ENABLED
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002049 if (filename == NULL) {
2050 if (generate) {
2051 xmlNodePtr n;
2052
2053 doc = xmlNewDoc(BAD_CAST "1.0");
Daniel Veillard95ddcd32004-10-26 21:53:55 +00002054 n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002055 xmlNodeSetContent(n, BAD_CAST "abc");
2056 xmlDocSetRootElement(doc, n);
2057 }
2058 }
Daniel Veillard652327a2003-09-29 18:02:38 +00002059#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002060#ifdef LIBXML_HTML_ENABLED
Daniel Veillard73b013f2003-09-30 12:36:01 +00002061#ifdef LIBXML_PUSH_ENABLED
William M. Brack78637da2003-07-31 14:47:38 +00002062 else if ((html) && (push)) {
2063 FILE *f;
2064
William M. Brack3403add2004-06-27 02:07:51 +00002065#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2066 f = fopen(filename, "rb");
2067#else
2068 f = fopen(filename, "r");
2069#endif
William M. Brack78637da2003-07-31 14:47:38 +00002070 if (f != NULL) {
2071 int res, size = 3;
2072 char chars[4096];
2073 htmlParserCtxtPtr ctxt;
2074
2075 /* if (repeat) */
2076 size = 4096;
2077 res = fread(chars, 1, 4, f);
2078 if (res > 0) {
2079 ctxt = htmlCreatePushParserCtxt(NULL, NULL,
William M. Brack1d75c8a2003-10-27 13:48:16 +00002080 chars, res, filename, XML_CHAR_ENCODING_NONE);
William M. Brack78637da2003-07-31 14:47:38 +00002081 while ((res = fread(chars, 1, size, f)) > 0) {
2082 htmlParseChunk(ctxt, chars, res, 0);
2083 }
2084 htmlParseChunk(ctxt, chars, 0, 1);
2085 doc = ctxt->myDoc;
2086 htmlFreeParserCtxt(ctxt);
2087 }
2088 fclose(f);
2089 }
2090 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00002091#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002092 else if (html) {
Daniel Veillard9475a352003-09-26 12:47:50 +00002093 doc = htmlReadFile(filename, NULL, options);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002094 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002095#endif /* LIBXML_HTML_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002096 else {
Daniel Veillard73b013f2003-09-30 12:36:01 +00002097#ifdef LIBXML_PUSH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002098 /*
2099 * build an XML tree from a string;
2100 */
2101 if (push) {
2102 FILE *f;
2103
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002104 /* '-' Usually means stdin -<sven@zen.org> */
2105 if ((filename[0] == '-') && (filename[1] == 0)) {
2106 f = stdin;
2107 } else {
William M. Brack3403add2004-06-27 02:07:51 +00002108#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2109 f = fopen(filename, "rb");
2110#else
2111 f = fopen(filename, "r");
2112#endif
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002113 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002114 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +00002115 int ret;
Daniel Veillarda880b122003-04-21 21:36:41 +00002116 int res, size = 1024;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002117 char chars[1024];
2118 xmlParserCtxtPtr ctxt;
2119
Daniel Veillarda880b122003-04-21 21:36:41 +00002120 /* if (repeat) size = 1024; */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002121 res = fread(chars, 1, 4, f);
2122 if (res > 0) {
2123 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
2124 chars, res, filename);
Daniel Veillard500a1de2004-03-22 15:22:58 +00002125 xmlCtxtUseOptions(ctxt, options);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002126 while ((res = fread(chars, 1, size, f)) > 0) {
2127 xmlParseChunk(ctxt, chars, res, 0);
2128 }
2129 xmlParseChunk(ctxt, chars, 0, 1);
2130 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +00002131 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002132 xmlFreeParserCtxt(ctxt);
Daniel Veillarde715dd22000-08-29 18:29:38 +00002133 if (!ret) {
2134 xmlFreeDoc(doc);
2135 doc = NULL;
2136 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002137 }
2138 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00002139 } else
2140#endif /* LIBXML_PUSH_ENABLED */
2141 if (testIO) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002142 if ((filename[0] == '-') && (filename[1] == 0)) {
Daniel Veillard60942de2003-09-25 21:05:58 +00002143 doc = xmlReadFd(0, NULL, NULL, options);
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002144 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002145 FILE *f;
Daniel Veillard5e873c42000-04-12 13:27:38 +00002146
William M. Brack3403add2004-06-27 02:07:51 +00002147#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2148 f = fopen(filename, "rb");
2149#else
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002150 f = fopen(filename, "r");
William M. Brack3403add2004-06-27 02:07:51 +00002151#endif
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002152 if (f != NULL) {
2153 if (rectxt == NULL)
2154 doc = xmlReadIO((xmlInputReadCallback) myRead,
2155 (xmlInputCloseCallback) myClose, f,
Daniel Veillard60942de2003-09-25 21:05:58 +00002156 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002157 else
2158 doc = xmlCtxtReadIO(rectxt,
2159 (xmlInputReadCallback) myRead,
2160 (xmlInputCloseCallback) myClose, f,
Daniel Veillard60942de2003-09-25 21:05:58 +00002161 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002162 } else
Daniel Veillard5e873c42000-04-12 13:27:38 +00002163 doc = NULL;
Daniel Veillard5e873c42000-04-12 13:27:38 +00002164 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002165 } else if (htmlout) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002166 xmlParserCtxtPtr ctxt;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002167
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002168 if (rectxt == NULL)
2169 ctxt = xmlNewParserCtxt();
2170 else
2171 ctxt = rectxt;
Daniel Veillard88a172f2000-08-04 18:23:10 +00002172 if (ctxt == NULL) {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002173 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +00002174 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002175 ctxt->sax->error = xmlHTMLError;
2176 ctxt->sax->warning = xmlHTMLWarning;
2177 ctxt->vctxt.error = xmlHTMLValidityError;
2178 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002179
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002180 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002181
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002182 if (rectxt == NULL)
2183 xmlFreeParserCtxt(ctxt);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002184 }
Daniel Veillard46e370e2000-07-21 20:32:03 +00002185#ifdef HAVE_SYS_MMAN_H
2186 } else if (memory) {
2187 int fd;
2188 struct stat info;
2189 const char *base;
2190 if (stat(filename, &info) < 0)
2191 return;
2192 if ((fd = open(filename, O_RDONLY)) < 0)
2193 return;
2194 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillard29579362000-08-14 17:57:48 +00002195 if (base == (void *) MAP_FAILED)
Daniel Veillard46e370e2000-07-21 20:32:03 +00002196 return;
2197
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002198 if (rectxt == NULL)
Daniel Veillard60942de2003-09-25 21:05:58 +00002199 doc = xmlReadMemory((char *) base, info.st_size,
2200 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002201 else
Daniel Veillard60942de2003-09-25 21:05:58 +00002202 doc = xmlCtxtReadMemory(rectxt, (char *) base, info.st_size,
2203 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002204
Daniel Veillard46e370e2000-07-21 20:32:03 +00002205 munmap((char *) base, info.st_size);
2206#endif
Daniel Veillard4432df22003-09-28 18:58:27 +00002207#ifdef LIBXML_VALID_ENABLED
Daniel Veillardea7751d2002-12-20 00:16:24 +00002208 } else if (valid) {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002209 xmlParserCtxtPtr ctxt = NULL;
Daniel Veillardea7751d2002-12-20 00:16:24 +00002210
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002211 if (rectxt == NULL)
2212 ctxt = xmlNewParserCtxt();
2213 else
2214 ctxt = rectxt;
Daniel Veillardea7751d2002-12-20 00:16:24 +00002215 if (ctxt == NULL) {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002216 doc = NULL;
Daniel Veillardea7751d2002-12-20 00:16:24 +00002217 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002218 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
2219
2220 if (ctxt->valid == 0)
William M. Brack8304d872004-06-08 13:29:32 +00002221 progresult = XMLLINT_ERR_RDFILE;
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002222 if (rectxt == NULL)
2223 xmlFreeParserCtxt(ctxt);
Daniel Veillardea7751d2002-12-20 00:16:24 +00002224 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002225#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardea7751d2002-12-20 00:16:24 +00002226 } else {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002227 if (rectxt != NULL)
2228 doc = xmlCtxtReadFile(rectxt, filename, NULL, options);
Daniel Veillard81562d22005-06-15 13:27:56 +00002229 else {
2230#ifdef LIBXML_SAX1_ENABLED
2231 if (sax1)
2232 doc = xmlParseFile(filename);
2233 else
2234#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002235 doc = xmlReadFile(filename, NULL, options);
Daniel Veillard81562d22005-06-15 13:27:56 +00002236 }
Daniel Veillardea7751d2002-12-20 00:16:24 +00002237 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002238 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002239
Daniel Veillard88a172f2000-08-04 18:23:10 +00002240 /*
2241 * If we don't have a document we might as well give up. Do we
2242 * want an error message here? <sven@zen.org> */
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002243 if (doc == NULL) {
William M. Brack8304d872004-06-08 13:29:32 +00002244 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard88a172f2000-08-04 18:23:10 +00002245 return;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002246 }
2247
Daniel Veillard48b2f892001-02-25 16:11:03 +00002248 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002249 endTimer("Parsing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002250 }
2251
Daniel Veillard29e43992001-12-13 22:21:58 +00002252 /*
2253 * Remove DOCTYPE nodes
2254 */
2255 if (dropdtd) {
2256 xmlDtdPtr dtd;
2257
2258 dtd = xmlGetIntSubset(doc);
2259 if (dtd != NULL) {
2260 xmlUnlinkNode((xmlNodePtr)dtd);
2261 xmlFreeDtd(dtd);
2262 }
2263 }
2264
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002265#ifdef LIBXML_XINCLUDE_ENABLED
Daniel Veillard48b2f892001-02-25 16:11:03 +00002266 if (xinclude) {
2267 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002268 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002269 }
William M. Brack4e1c2db2005-02-11 10:58:55 +00002270 if (xmlXIncludeProcessFlags(doc, options) < 0)
2271 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard48b2f892001-02-25 16:11:03 +00002272 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002273 endTimer("Xinclude processing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002274 }
2275 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002276#endif
Daniel Veillard88a172f2000-08-04 18:23:10 +00002277
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002278#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00002279#ifdef LIBXML_XPATH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002280 /*
Daniel Veillardcbaf3992001-12-31 16:16:02 +00002281 * shell interaction
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002282 */
2283 if (shell)
2284 xmlShell(doc, filename, xmlShellReadline, stdout);
2285#endif
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00002286#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002287
Daniel Veillard652327a2003-09-29 18:02:38 +00002288#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002289 /*
2290 * test intermediate copy if needed.
2291 */
2292 if (copy) {
2293 tmp = doc;
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002294 if (timing) {
2295 startTimer();
2296 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002297 doc = xmlCopyDoc(doc, 1);
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002298 if (timing) {
2299 endTimer("Copying");
2300 }
2301 if (timing) {
2302 startTimer();
2303 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002304 xmlFreeDoc(tmp);
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002305 if (timing) {
2306 endTimer("Freeing original");
2307 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002308 }
Daniel Veillard652327a2003-09-29 18:02:38 +00002309#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002310
Daniel Veillard4432df22003-09-28 18:58:27 +00002311#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002312 if ((insert) && (!html)) {
2313 const xmlChar* list[256];
2314 int nb, i;
2315 xmlNodePtr node;
2316
2317 if (doc->children != NULL) {
2318 node = doc->children;
2319 while ((node != NULL) && (node->last == NULL)) node = node->next;
2320 if (node != NULL) {
2321 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
2322 if (nb < 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002323 fprintf(stderr, "could not get valid list of elements\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002324 } else if (nb == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002325 fprintf(stderr, "No element can be inserted under root\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002326 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002327 fprintf(stderr, "%d element types can be inserted under root:\n",
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002328 nb);
2329 for (i = 0;i < nb;i++) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002330 fprintf(stderr, "%s\n", (char *) list[i]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002331 }
2332 }
2333 }
2334 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002335 }else
2336#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002337#ifdef LIBXML_READER_ENABLED
2338 if (walker) {
2339 walkDoc(doc);
2340 }
2341#endif /* LIBXML_READER_ENABLED */
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002342#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard4432df22003-09-28 18:58:27 +00002343 if (noout == 0) {
Daniel Veillard3df01182003-12-10 10:17:51 +00002344 int ret;
2345
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002346 /*
2347 * print it.
2348 */
2349#ifdef LIBXML_DEBUG_ENABLED
2350 if (!debug) {
2351#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00002352 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002353 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002354 }
Daniel Veillard656ce942004-04-30 23:11:45 +00002355#ifdef LIBXML_HTML_ENABLED
Daniel Veillard42fd4122003-11-04 08:47:48 +00002356 if ((html) && (!xmlout)) {
2357 if (compress) {
2358 htmlSaveFile(output ? output : "-", doc);
2359 }
2360 else if (encoding != NULL) {
2361 if ( format ) {
2362 htmlSaveFileFormat(output ? output : "-", doc, encoding, 1);
2363 }
2364 else {
2365 htmlSaveFileFormat(output ? output : "-", doc, encoding, 0);
2366 }
2367 }
2368 else if (format) {
2369 htmlSaveFileFormat(output ? output : "-", doc, NULL, 1);
2370 }
2371 else {
2372 FILE *out;
2373 if (output == NULL)
2374 out = stdout;
2375 else {
2376 out = fopen(output,"wb");
2377 }
2378 if (out != NULL) {
2379 if (htmlDocDump(out, doc) < 0)
William M. Brack8304d872004-06-08 13:29:32 +00002380 progresult = XMLLINT_ERR_OUT;
Daniel Veillard42fd4122003-11-04 08:47:48 +00002381
2382 if (output != NULL)
2383 fclose(out);
2384 } else {
2385 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00002386 progresult = XMLLINT_ERR_OUT;
Daniel Veillard42fd4122003-11-04 08:47:48 +00002387 }
2388 }
2389 if ((timing) && (!repeat)) {
2390 endTimer("Saving");
2391 }
2392 } else
2393#endif
Daniel Veillard25048d82004-08-14 22:37:54 +00002394#ifdef LIBXML_C14N_ENABLED
2395 if (canonical) {
2396 xmlChar *result = NULL;
2397 int size;
2398
2399 size = xmlC14NDocDumpMemory(doc, NULL, 0, NULL, 1, &result);
2400 if (size >= 0) {
2401 write(1, result, size);
2402 xmlFree(result);
2403 } else {
2404 fprintf(stderr, "Failed to canonicalize\n");
2405 progresult = XMLLINT_ERR_OUT;
2406 }
2407 } else
Aleksey Sanin2650df12005-06-06 17:16:50 +00002408 if (exc_canonical) {
2409 xmlChar *result = NULL;
2410 int size;
2411
2412 size = xmlC14NDocDumpMemory(doc, NULL, 1, NULL, 1, &result);
2413 if (size >= 0) {
2414 write(1, result, size);
2415 xmlFree(result);
2416 } else {
2417 fprintf(stderr, "Failed to canonicalize\n");
2418 progresult = XMLLINT_ERR_OUT;
2419 }
2420 } else
Daniel Veillard25048d82004-08-14 22:37:54 +00002421#endif
Daniel Veillard3b2c2612001-04-04 00:09:00 +00002422#ifdef HAVE_SYS_MMAN_H
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002423 if (memory) {
2424 xmlChar *result;
2425 int len;
2426
2427 if (encoding != NULL) {
Daniel Veillardd536f702001-11-08 17:32:47 +00002428 if ( format ) {
2429 xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
2430 } else {
2431 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
2432 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002433 } else {
Daniel Veillard90493a92001-08-14 14:12:47 +00002434 if (format)
2435 xmlDocDumpFormatMemory(doc, &result, &len, 1);
2436 else
2437 xmlDocDumpMemory(doc, &result, &len);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002438 }
2439 if (result == NULL) {
2440 fprintf(stderr, "Failed to save\n");
Daniel Veillard25048d82004-08-14 22:37:54 +00002441 progresult = XMLLINT_ERR_OUT;
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002442 } else {
2443 write(1, result, len);
2444 xmlFree(result);
2445 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +00002446 } else
2447#endif /* HAVE_SYS_MMAN_H */
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002448 if (compress) {
2449 xmlSaveFile(output ? output : "-", doc);
2450 }
Daniel Veillardd536f702001-11-08 17:32:47 +00002451 else if (encoding != NULL) {
2452 if ( format ) {
Daniel Veillard3df01182003-12-10 10:17:51 +00002453 ret = xmlSaveFormatFileEnc(output ? output : "-", doc,
2454 encoding, 1);
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002455 }
Daniel Veillardd536f702001-11-08 17:32:47 +00002456 else {
Daniel Veillard3df01182003-12-10 10:17:51 +00002457 ret = xmlSaveFileEnc(output ? output : "-", doc, encoding);
2458 }
2459 if (ret < 0) {
2460 fprintf(stderr, "failed save to %s\n",
2461 output ? output : "-");
William M. Brack8304d872004-06-08 13:29:32 +00002462 progresult = XMLLINT_ERR_OUT;
Daniel Veillardd536f702001-11-08 17:32:47 +00002463 }
2464 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002465 else if (format) {
Daniel Veillard3df01182003-12-10 10:17:51 +00002466 ret = xmlSaveFormatFile(output ? output : "-", doc, 1);
2467 if (ret < 0) {
2468 fprintf(stderr, "failed save to %s\n",
2469 output ? output : "-");
William M. Brack8304d872004-06-08 13:29:32 +00002470 progresult = XMLLINT_ERR_OUT;
Daniel Veillard3df01182003-12-10 10:17:51 +00002471 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002472 }
2473 else {
2474 FILE *out;
2475 if (output == NULL)
2476 out = stdout;
2477 else {
2478 out = fopen(output,"wb");
2479 }
Daniel Veillard05d987b2003-10-08 11:54:57 +00002480 if (out != NULL) {
Daniel Veillard828ce832003-10-08 19:19:10 +00002481 if (xmlDocDump(out, doc) < 0)
William M. Brack8304d872004-06-08 13:29:32 +00002482 progresult = XMLLINT_ERR_OUT;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002483
Daniel Veillard05d987b2003-10-08 11:54:57 +00002484 if (output != NULL)
2485 fclose(out);
2486 } else {
2487 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00002488 progresult = XMLLINT_ERR_OUT;
Daniel Veillard05d987b2003-10-08 11:54:57 +00002489 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002490 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002491 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002492 endTimer("Saving");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002493 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002494#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002495 } else {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002496 FILE *out;
2497 if (output == NULL)
2498 out = stdout;
2499 else {
2500 out = fopen(output,"wb");
2501 }
Daniel Veillard05d987b2003-10-08 11:54:57 +00002502 if (out != NULL) {
2503 xmlDebugDumpDocument(out, doc);
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002504
Daniel Veillard05d987b2003-10-08 11:54:57 +00002505 if (output != NULL)
2506 fclose(out);
2507 } else {
2508 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00002509 progresult = XMLLINT_ERR_OUT;
Daniel Veillard05d987b2003-10-08 11:54:57 +00002510 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002511 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002512#endif
2513 }
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002514#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002515
Daniel Veillard4432df22003-09-28 18:58:27 +00002516#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002517 /*
2518 * A posteriori validation test
2519 */
Daniel Veillard66f68e72003-08-18 16:39:51 +00002520 if ((dtdvalid != NULL) || (dtdvalidfpi != NULL)) {
Daniel Veillardcd429612000-10-11 15:57:05 +00002521 xmlDtdPtr dtd;
2522
Daniel Veillard48b2f892001-02-25 16:11:03 +00002523 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002524 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002525 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00002526 if (dtdvalid != NULL)
2527 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
2528 else
2529 dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL);
Daniel Veillard48b2f892001-02-25 16:11:03 +00002530 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002531 endTimer("Parsing DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002532 }
Daniel Veillardcd429612000-10-11 15:57:05 +00002533 if (dtd == NULL) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00002534 if (dtdvalid != NULL)
2535 xmlGenericError(xmlGenericErrorContext,
2536 "Could not parse DTD %s\n", dtdvalid);
2537 else
2538 xmlGenericError(xmlGenericErrorContext,
2539 "Could not parse DTD %s\n", dtdvalidfpi);
William M. Brack8304d872004-06-08 13:29:32 +00002540 progresult = XMLLINT_ERR_DTD;
Daniel Veillardcd429612000-10-11 15:57:05 +00002541 } else {
Daniel Veillarda37aab82003-06-09 09:10:36 +00002542 xmlValidCtxtPtr cvp;
2543
2544 if ((cvp = xmlNewValidCtxt()) == NULL) {
2545 xmlGenericError(xmlGenericErrorContext,
2546 "Couldn't allocate validation context\n");
2547 exit(-1);
2548 }
2549 cvp->userData = (void *) stderr;
2550 cvp->error = (xmlValidityErrorFunc) fprintf;
2551 cvp->warning = (xmlValidityWarningFunc) fprintf;
2552
Daniel Veillard48b2f892001-02-25 16:11:03 +00002553 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002554 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002555 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002556 if (!xmlValidateDtd(cvp, doc, dtd)) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00002557 if (dtdvalid != NULL)
2558 xmlGenericError(xmlGenericErrorContext,
2559 "Document %s does not validate against %s\n",
2560 filename, dtdvalid);
2561 else
2562 xmlGenericError(xmlGenericErrorContext,
2563 "Document %s does not validate against %s\n",
2564 filename, dtdvalidfpi);
William M. Brack8304d872004-06-08 13:29:32 +00002565 progresult = XMLLINT_ERR_VALID;
Daniel Veillardcd429612000-10-11 15:57:05 +00002566 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002567 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002568 endTimer("Validating against DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002569 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002570 xmlFreeValidCtxt(cvp);
Daniel Veillardcd429612000-10-11 15:57:05 +00002571 xmlFreeDtd(dtd);
2572 }
2573 } else if (postvalid) {
Daniel Veillarda37aab82003-06-09 09:10:36 +00002574 xmlValidCtxtPtr cvp;
2575
2576 if ((cvp = xmlNewValidCtxt()) == NULL) {
2577 xmlGenericError(xmlGenericErrorContext,
2578 "Couldn't allocate validation context\n");
2579 exit(-1);
2580 }
2581
Daniel Veillard48b2f892001-02-25 16:11:03 +00002582 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002583 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002584 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002585 cvp->userData = (void *) stderr;
2586 cvp->error = (xmlValidityErrorFunc) fprintf;
2587 cvp->warning = (xmlValidityWarningFunc) fprintf;
2588 if (!xmlValidateDocument(cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00002589 xmlGenericError(xmlGenericErrorContext,
2590 "Document %s does not validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002591 progresult = XMLLINT_ERR_VALID;
Daniel Veillardcd429612000-10-11 15:57:05 +00002592 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002593 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002594 endTimer("Validating");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002595 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002596 xmlFreeValidCtxt(cvp);
Daniel Veillard4432df22003-09-28 18:58:27 +00002597 }
2598#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardd4501d72005-07-24 14:27:16 +00002599#ifdef LIBXML_SCHEMATRON_ENABLED
2600 if (wxschematron != NULL) {
2601 xmlSchematronValidCtxtPtr ctxt;
2602 int ret;
Daniel Veillardc740a172005-07-31 12:17:24 +00002603 int flag;
Daniel Veillardd4501d72005-07-24 14:27:16 +00002604
2605 if ((timing) && (!repeat)) {
2606 startTimer();
2607 }
2608
2609 if (debug)
2610 flag = XML_SCHEMATRON_OUT_XML;
Daniel Veillardc740a172005-07-31 12:17:24 +00002611 else
2612 flag = XML_SCHEMATRON_OUT_TEXT;
2613 if (noout)
2614 flag |= XML_SCHEMATRON_OUT_QUIET;
Daniel Veillardd4501d72005-07-24 14:27:16 +00002615 ctxt = xmlSchematronNewValidCtxt(wxschematron, flag);
2616#if 0
2617 xmlSchematronSetValidErrors(ctxt,
2618 (xmlSchematronValidityErrorFunc) fprintf,
2619 (xmlSchematronValidityWarningFunc) fprintf,
2620 stderr);
2621#endif
2622 ret = xmlSchematronValidateDoc(ctxt, doc);
2623 if (ret == 0) {
2624 fprintf(stderr, "%s validates\n", filename);
2625 } else if (ret > 0) {
2626 fprintf(stderr, "%s fails to validate\n", filename);
2627 progresult = XMLLINT_ERR_VALID;
2628 } else {
2629 fprintf(stderr, "%s validation generated an internal error\n",
2630 filename);
2631 progresult = XMLLINT_ERR_VALID;
2632 }
2633 xmlSchematronFreeValidCtxt(ctxt);
2634 if ((timing) && (!repeat)) {
2635 endTimer("Validating");
2636 }
2637 }
2638#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00002639#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard4432df22003-09-28 18:58:27 +00002640 if (relaxngschemas != NULL) {
Daniel Veillard71531f32003-02-05 13:19:53 +00002641 xmlRelaxNGValidCtxtPtr ctxt;
2642 int ret;
2643
Daniel Veillard42f12e92003-03-07 18:32:59 +00002644 if ((timing) && (!repeat)) {
2645 startTimer();
2646 }
2647
Daniel Veillard71531f32003-02-05 13:19:53 +00002648 ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
2649 xmlRelaxNGSetValidErrors(ctxt,
2650 (xmlRelaxNGValidityErrorFunc) fprintf,
2651 (xmlRelaxNGValidityWarningFunc) fprintf,
2652 stderr);
2653 ret = xmlRelaxNGValidateDoc(ctxt, doc);
2654 if (ret == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002655 fprintf(stderr, "%s validates\n", filename);
Daniel Veillard71531f32003-02-05 13:19:53 +00002656 } else if (ret > 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002657 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002658 progresult = XMLLINT_ERR_VALID;
Daniel Veillard71531f32003-02-05 13:19:53 +00002659 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002660 fprintf(stderr, "%s validation generated an internal error\n",
Daniel Veillard71531f32003-02-05 13:19:53 +00002661 filename);
William M. Brack8304d872004-06-08 13:29:32 +00002662 progresult = XMLLINT_ERR_VALID;
Daniel Veillard71531f32003-02-05 13:19:53 +00002663 }
2664 xmlRelaxNGFreeValidCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00002665 if ((timing) && (!repeat)) {
2666 endTimer("Validating");
2667 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002668 } else if (wxschemas != NULL) {
2669 xmlSchemaValidCtxtPtr ctxt;
2670 int ret;
2671
2672 if ((timing) && (!repeat)) {
2673 startTimer();
2674 }
2675
2676 ctxt = xmlSchemaNewValidCtxt(wxschemas);
2677 xmlSchemaSetValidErrors(ctxt,
2678 (xmlSchemaValidityErrorFunc) fprintf,
2679 (xmlSchemaValidityWarningFunc) fprintf,
2680 stderr);
2681 ret = xmlSchemaValidateDoc(ctxt, doc);
2682 if (ret == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002683 fprintf(stderr, "%s validates\n", filename);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002684 } else if (ret > 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002685 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002686 progresult = XMLLINT_ERR_VALID;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002687 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002688 fprintf(stderr, "%s validation generated an internal error\n",
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002689 filename);
William M. Brack8304d872004-06-08 13:29:32 +00002690 progresult = XMLLINT_ERR_VALID;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002691 }
2692 xmlSchemaFreeValidCtxt(ctxt);
2693 if ((timing) && (!repeat)) {
2694 endTimer("Validating");
2695 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002696 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002697#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002698
2699#ifdef LIBXML_DEBUG_ENABLED
2700 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00002701 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002702#endif
2703
2704 /*
2705 * free it.
2706 */
Daniel Veillard48b2f892001-02-25 16:11:03 +00002707 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002708 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002709 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002710 xmlFreeDoc(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +00002711 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002712 endTimer("Freeing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002713 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002714}
2715
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002716/************************************************************************
2717 * *
2718 * Usage and Main *
2719 * *
2720 ************************************************************************/
2721
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002722static void showVersion(const char *name) {
2723 fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
2724 fprintf(stderr, " compiled with: ");
Daniel Veillard602434d2005-09-12 09:20:31 +00002725 if (xmlHasFeature(XML_WITH_THREAD)) fprintf(stderr, "Threads ");
2726 if (xmlHasFeature(XML_WITH_TREE)) fprintf(stderr, "Tree ");
2727 if (xmlHasFeature(XML_WITH_OUTPUT)) fprintf(stderr, "Output ");
2728 if (xmlHasFeature(XML_WITH_PUSH)) fprintf(stderr, "Push ");
2729 if (xmlHasFeature(XML_WITH_READER)) fprintf(stderr, "Reader ");
2730 if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(stderr, "Patterns ");
2731 if (xmlHasFeature(XML_WITH_WRITER)) fprintf(stderr, "Writer ");
2732 if (xmlHasFeature(XML_WITH_SAX1)) fprintf(stderr, "SAXv1 ");
2733 if (xmlHasFeature(XML_WITH_FTP)) fprintf(stderr, "FTP ");
2734 if (xmlHasFeature(XML_WITH_HTTP)) fprintf(stderr, "HTTP ");
2735 if (xmlHasFeature(XML_WITH_VALID)) fprintf(stderr, "DTDValid ");
2736 if (xmlHasFeature(XML_WITH_HTML)) fprintf(stderr, "HTML ");
2737 if (xmlHasFeature(XML_WITH_LEGACY)) fprintf(stderr, "Legacy ");
2738 if (xmlHasFeature(XML_WITH_C14N)) fprintf(stderr, "C14N ");
2739 if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(stderr, "Catalog ");
2740 if (xmlHasFeature(XML_WITH_XPATH)) fprintf(stderr, "XPath ");
2741 if (xmlHasFeature(XML_WITH_XPTR)) fprintf(stderr, "XPointer ");
2742 if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(stderr, "XInclude ");
2743 if (xmlHasFeature(XML_WITH_ICONV)) fprintf(stderr, "Iconv ");
2744 if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(stderr, "ISO8859X ");
2745 if (xmlHasFeature(XML_WITH_UNICODE)) fprintf(stderr, "Unicode ");
2746 if (xmlHasFeature(XML_WITH_REGEXP)) fprintf(stderr, "Regexps ");
2747 if (xmlHasFeature(XML_WITH_AUTOMATA)) fprintf(stderr, "Automata ");
2748 if (xmlHasFeature(XML_WITH_EXPR)) fprintf(stderr, "Expr ");
2749 if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(stderr, "Schemas ");
2750 if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(stderr, "Schematron ");
2751 if (xmlHasFeature(XML_WITH_MODULES)) fprintf(stderr, "Modules ");
2752 if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(stderr, "Debug ");
2753 if (xmlHasFeature(XML_WITH_DEBUG_MEM)) fprintf(stderr, "MemDebug ");
2754 if (xmlHasFeature(XML_WITH_DEBUG_RUN)) fprintf(stderr, "RunDebug ");
Daniel Veillard75acfee2006-07-13 06:29:56 +00002755 if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(stderr, "Zlib ");
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002756 fprintf(stderr, "\n");
2757}
2758
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002759static void usage(const char *name) {
2760 printf("Usage : %s [options] XMLfiles ...\n", name);
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002761#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002762 printf("\tParse the XML files and output the result of the parsing\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002763#else
2764 printf("\tParse the XML files\n");
2765#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002766 printf("\t--version : display the version of the XML library used\n");
2767#ifdef LIBXML_DEBUG_ENABLED
2768 printf("\t--debug : dump a debug tree of the in-memory document\n");
2769 printf("\t--shell : run a navigating shell\n");
2770 printf("\t--debugent : debug the entities defined in the document\n");
Daniel Veillard8326e732003-01-07 00:19:07 +00002771#else
Daniel Veillard81273902003-09-30 00:43:48 +00002772#ifdef LIBXML_READER_ENABLED
Daniel Veillard8326e732003-01-07 00:19:07 +00002773 printf("\t--debug : dump the nodes content when using --stream\n");
Daniel Veillard81273902003-09-30 00:43:48 +00002774#endif /* LIBXML_READER_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002775#endif
Daniel Veillard652327a2003-09-29 18:02:38 +00002776#ifdef LIBXML_TREE_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002777 printf("\t--copy : used to test the internal copy implementation\n");
Daniel Veillard652327a2003-09-29 18:02:38 +00002778#endif /* LIBXML_TREE_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002779 printf("\t--recover : output what was parsable on broken XML documents\n");
2780 printf("\t--noent : substitute entity references by their value\n");
2781 printf("\t--noout : don't output the result tree\n");
Daniel Veillard0bff36d2004-08-31 09:37:03 +00002782 printf("\t--path 'paths': provide a set of paths for resources\n");
2783 printf("\t--load-trace : print trace of all external entites loaded\n");
Daniel Veillarde8b09e42003-05-13 22:14:13 +00002784 printf("\t--nonet : refuse to fetch DTDs or entities over network\n");
Daniel Veillard8874b942005-08-25 13:19:21 +00002785 printf("\t--nocompact : do not generate compact text nodes\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002786 printf("\t--htmlout : output results as HTML\n");
Daniel Veillard05c13a22001-09-09 08:38:09 +00002787 printf("\t--nowrap : do not put HTML doc wrapper\n");
Daniel Veillard4432df22003-09-28 18:58:27 +00002788#ifdef LIBXML_VALID_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002789 printf("\t--valid : validate the document in addition to std well-formed check\n");
2790 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
2791 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
Daniel Veillard66f68e72003-08-18 16:39:51 +00002792 printf("\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
Daniel Veillard4432df22003-09-28 18:58:27 +00002793#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002794 printf("\t--timing : print some timings\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002795 printf("\t--output file or -o file: save to a given file\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002796 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
2797 printf("\t--insert : ad-hoc test for valid insertions\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002798#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002799#ifdef HAVE_ZLIB_H
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002800 printf("\t--compress : turn on gzip compression of output\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002801#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002802#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002803#ifdef LIBXML_HTML_ENABLED
2804 printf("\t--html : use the HTML parser\n");
Daniel Veillard42fd4122003-11-04 08:47:48 +00002805 printf("\t--xmlout : force to use the XML serializer when using --html\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002806#endif
Daniel Veillard73b013f2003-09-30 12:36:01 +00002807#ifdef LIBXML_PUSH_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002808 printf("\t--push : use the push mode of the parser\n");
Daniel Veillard73b013f2003-09-30 12:36:01 +00002809#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002810#ifdef HAVE_SYS_MMAN_H
2811 printf("\t--memory : parse from memory\n");
2812#endif
Daniel Veillard87076042004-05-03 22:54:49 +00002813 printf("\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002814 printf("\t--nowarning : do not emit warnings from parser/validator\n");
2815 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
Daniel Veillarddca8cc72003-09-26 13:53:14 +00002816 printf("\t--nocdata : replace cdata section with text nodes\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002817#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard90493a92001-08-14 14:12:47 +00002818 printf("\t--format : reformat/reindent the input\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002819 printf("\t--encode encoding : output in the given encoding\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002820 printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
2821#endif /* LIBXML_OUTPUT_ENABLED */
Aleksey Sanin2650df12005-06-06 17:16:50 +00002822 printf("\t--c14n : save in W3C canonical format (with comments)\n");
2823 printf("\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n");
Daniel Veillard25048d82004-08-14 22:37:54 +00002824#ifdef LIBXML_C14N_ENABLED
2825#endif /* LIBXML_C14N_ENABLED */
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002826 printf("\t--nsclean : remove redundant namespace declarations\n");
2827 printf("\t--testIO : test user I/O support\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002828#ifdef LIBXML_CATALOG_ENABLED
Daniel Veillardbd9b0e82001-11-26 10:32:08 +00002829 printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
2830 printf("\t otherwise XML Catalogs starting from \n");
Daniel Veillardb3de70c2003-12-02 22:32:15 +00002831 printf("\t %s are activated by default\n", XML_XML_DEFAULT_CATALOG);
Daniel Veillard05c13a22001-09-09 08:38:09 +00002832 printf("\t--nocatalogs: deactivate all catalogs\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002833#endif
2834 printf("\t--auto : generate a small doc on the fly\n");
2835#ifdef LIBXML_XINCLUDE_ENABLED
2836 printf("\t--xinclude : do XInclude processing\n");
Daniel Veillardc14c3892004-08-16 12:34:50 +00002837 printf("\t--noxincludenode : same but do not generate XInclude nodes\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002838#endif
Daniel Veillardcbaf3992001-12-31 16:16:02 +00002839 printf("\t--loaddtd : fetch external DTD\n");
Daniel Veillard48da9102001-08-07 01:10:10 +00002840 printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
Daniel Veillard81273902003-09-30 00:43:48 +00002841#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00002842 printf("\t--stream : use the streaming interface to process very large files\n");
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002843 printf("\t--walker : create a reader and walk though the resulting doc\n");
Daniel Veillard81273902003-09-30 00:43:48 +00002844#endif /* LIBXML_READER_ENABLED */
Daniel Veillardb3de70c2003-12-02 22:32:15 +00002845#ifdef LIBXML_PATTERN_ENABLED
2846 printf("\t--pattern pattern_value : test the pattern support\n");
2847#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00002848 printf("\t--chkregister : verify the node registration code\n");
Daniel Veillardef4d3bc2003-02-07 12:38:22 +00002849#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard71531f32003-02-05 13:19:53 +00002850 printf("\t--relaxng schema : do RelaxNG validation against the schema\n");
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002851 printf("\t--schema schema : do validation against the WXS schema\n");
Daniel Veillard71531f32003-02-05 13:19:53 +00002852#endif
Daniel Veillarde70375c2005-07-30 21:09:12 +00002853#ifdef LIBXML_SCHEMATRON_ENABLED
2854 printf("\t--schematron schema : do validation against a schematron\n");
2855#endif
Daniel Veillard971771e2005-07-09 17:32:57 +00002856#ifdef LIBXML_SAX1_ENABLED
2857 printf("\t--sax1: use the old SAX1 interfaces for processing\n");
2858#endif
2859 printf("\t--sax: do not build a tree but work just at the SAX level\n");
2860
Daniel Veillarda42f25f2002-01-25 14:15:40 +00002861 printf("\nLibxml project home page: http://xmlsoft.org/\n");
2862 printf("To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002863}
Daniel Veillard8a1b1852003-01-05 22:37:17 +00002864
2865static void registerNode(xmlNodePtr node)
2866{
2867 node->_private = malloc(sizeof(long));
2868 *(long*)node->_private = (long) 0x81726354;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00002869 nbregister++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00002870}
2871
2872static void deregisterNode(xmlNodePtr node)
2873{
2874 assert(node->_private != NULL);
2875 assert(*(long*)node->_private == (long) 0x81726354);
2876 free(node->_private);
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00002877 nbregister--;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00002878}
2879
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002880int
2881main(int argc, char **argv) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00002882 int i, acount;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002883 int files = 0;
Daniel Veillard845cce42002-01-09 11:51:37 +00002884 int version = 0;
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00002885 const char* indent;
2886
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002887 if (argc <= 1) {
2888 usage(argv[0]);
2889 return(1);
2890 }
Daniel Veillardbe803962000-06-28 23:40:59 +00002891 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002892 for (i = 1; i < argc ; i++) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002893 if (!strcmp(argv[i], "-"))
2894 break;
2895
2896 if (argv[i][0] != '-')
2897 continue;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002898 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
2899 debug++;
Daniel Veillard56ada1d2003-01-07 11:17:25 +00002900 else
2901#ifdef LIBXML_DEBUG_ENABLED
2902 if ((!strcmp(argv[i], "-shell")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002903 (!strcmp(argv[i], "--shell"))) {
2904 shell++;
2905 noout = 1;
2906 } else
2907#endif
Daniel Veillard652327a2003-09-29 18:02:38 +00002908#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002909 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
2910 copy++;
Daniel Veillard652327a2003-09-29 18:02:38 +00002911 else
2912#endif /* LIBXML_TREE_ENABLED */
2913 if ((!strcmp(argv[i], "-recover")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002914 (!strcmp(argv[i], "--recover"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002915 recovery++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002916 options |= XML_PARSE_RECOVER;
2917 } else if ((!strcmp(argv[i], "-noent")) ||
2918 (!strcmp(argv[i], "--noent"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002919 noent++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002920 options |= XML_PARSE_NOENT;
Daniel Veillarddca8cc72003-09-26 13:53:14 +00002921 } else if ((!strcmp(argv[i], "-nsclean")) ||
2922 (!strcmp(argv[i], "--nsclean"))) {
2923 options |= XML_PARSE_NSCLEAN;
2924 } else if ((!strcmp(argv[i], "-nocdata")) ||
2925 (!strcmp(argv[i], "--nocdata"))) {
2926 options |= XML_PARSE_NOCDATA;
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002927 } else if ((!strcmp(argv[i], "-nodict")) ||
2928 (!strcmp(argv[i], "--nodict"))) {
2929 options |= XML_PARSE_NODICT;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002930 } else if ((!strcmp(argv[i], "-version")) ||
Daniel Veillard845cce42002-01-09 11:51:37 +00002931 (!strcmp(argv[i], "--version"))) {
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002932 showVersion(argv[0]);
Daniel Veillard845cce42002-01-09 11:51:37 +00002933 version = 1;
2934 } else if ((!strcmp(argv[i], "-noout")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002935 (!strcmp(argv[i], "--noout")))
2936 noout++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002937#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002938 else if ((!strcmp(argv[i], "-o")) ||
2939 (!strcmp(argv[i], "-output")) ||
2940 (!strcmp(argv[i], "--output"))) {
2941 i++;
Daniel Veillard6e4f1c02002-04-09 09:55:20 +00002942 output = argv[i];
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002943 }
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002944#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002945 else if ((!strcmp(argv[i], "-htmlout")) ||
2946 (!strcmp(argv[i], "--htmlout")))
2947 htmlout++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002948 else if ((!strcmp(argv[i], "-nowrap")) ||
2949 (!strcmp(argv[i], "--nowrap")))
2950 nowrap++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002951#ifdef LIBXML_HTML_ENABLED
2952 else if ((!strcmp(argv[i], "-html")) ||
2953 (!strcmp(argv[i], "--html"))) {
2954 html++;
2955 }
Daniel Veillard42fd4122003-11-04 08:47:48 +00002956 else if ((!strcmp(argv[i], "-xmlout")) ||
2957 (!strcmp(argv[i], "--xmlout"))) {
2958 xmlout++;
2959 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002960#endif /* LIBXML_HTML_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002961 else if ((!strcmp(argv[i], "-loaddtd")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002962 (!strcmp(argv[i], "--loaddtd"))) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002963 loaddtd++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002964 options |= XML_PARSE_DTDLOAD;
2965 } else if ((!strcmp(argv[i], "-dtdattr")) ||
Daniel Veillard48da9102001-08-07 01:10:10 +00002966 (!strcmp(argv[i], "--dtdattr"))) {
2967 loaddtd++;
2968 dtdattrs++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002969 options |= XML_PARSE_DTDATTR;
Daniel Veillard4432df22003-09-28 18:58:27 +00002970 }
2971#ifdef LIBXML_VALID_ENABLED
2972 else if ((!strcmp(argv[i], "-valid")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002973 (!strcmp(argv[i], "--valid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002974 valid++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002975 options |= XML_PARSE_DTDVALID;
2976 } else if ((!strcmp(argv[i], "-postvalid")) ||
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002977 (!strcmp(argv[i], "--postvalid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002978 postvalid++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002979 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00002980 options |= XML_PARSE_DTDLOAD;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002981 } else if ((!strcmp(argv[i], "-dtdvalid")) ||
Daniel Veillardcd429612000-10-11 15:57:05 +00002982 (!strcmp(argv[i], "--dtdvalid"))) {
2983 i++;
2984 dtdvalid = argv[i];
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002985 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00002986 options |= XML_PARSE_DTDLOAD;
Daniel Veillard66f68e72003-08-18 16:39:51 +00002987 } else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
2988 (!strcmp(argv[i], "--dtdvalidfpi"))) {
2989 i++;
2990 dtdvalidfpi = argv[i];
2991 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00002992 options |= XML_PARSE_DTDLOAD;
Daniel Veillardcd429612000-10-11 15:57:05 +00002993 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002994#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard29e43992001-12-13 22:21:58 +00002995 else if ((!strcmp(argv[i], "-dropdtd")) ||
2996 (!strcmp(argv[i], "--dropdtd")))
2997 dropdtd++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002998 else if ((!strcmp(argv[i], "-insert")) ||
2999 (!strcmp(argv[i], "--insert")))
3000 insert++;
Daniel Veillard48b2f892001-02-25 16:11:03 +00003001 else if ((!strcmp(argv[i], "-timing")) ||
3002 (!strcmp(argv[i], "--timing")))
3003 timing++;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00003004 else if ((!strcmp(argv[i], "-auto")) ||
3005 (!strcmp(argv[i], "--auto")))
3006 generate++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003007 else if ((!strcmp(argv[i], "-repeat")) ||
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00003008 (!strcmp(argv[i], "--repeat"))) {
3009 if (repeat)
3010 repeat *= 10;
3011 else
3012 repeat = 100;
Daniel Veillard73b013f2003-09-30 12:36:01 +00003013 }
3014#ifdef LIBXML_PUSH_ENABLED
3015 else if ((!strcmp(argv[i], "-push")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003016 (!strcmp(argv[i], "--push")))
3017 push++;
Daniel Veillard73b013f2003-09-30 12:36:01 +00003018#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillard46e370e2000-07-21 20:32:03 +00003019#ifdef HAVE_SYS_MMAN_H
3020 else if ((!strcmp(argv[i], "-memory")) ||
3021 (!strcmp(argv[i], "--memory")))
3022 memory++;
3023#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +00003024 else if ((!strcmp(argv[i], "-testIO")) ||
3025 (!strcmp(argv[i], "--testIO")))
3026 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003027#ifdef LIBXML_XINCLUDE_ENABLED
3028 else if ((!strcmp(argv[i], "-xinclude")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003029 (!strcmp(argv[i], "--xinclude"))) {
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003030 xinclude++;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003031 options |= XML_PARSE_XINCLUDE;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003032 }
Daniel Veillardc14c3892004-08-16 12:34:50 +00003033 else if ((!strcmp(argv[i], "-noxincludenode")) ||
3034 (!strcmp(argv[i], "--noxincludenode"))) {
3035 xinclude++;
3036 options |= XML_PARSE_XINCLUDE;
3037 options |= XML_PARSE_NOXINCNODE;
3038 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003039#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003040#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003041#ifdef HAVE_ZLIB_H
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003042 else if ((!strcmp(argv[i], "-compress")) ||
3043 (!strcmp(argv[i], "--compress"))) {
3044 compress++;
3045 xmlSetCompressMode(9);
3046 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003047#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003048#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003049 else if ((!strcmp(argv[i], "-nowarning")) ||
3050 (!strcmp(argv[i], "--nowarning"))) {
3051 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003052 xmlPedanticParserDefault(0);
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003053 options |= XML_PARSE_NOWARNING;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003054 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003055 else if ((!strcmp(argv[i], "-pedantic")) ||
3056 (!strcmp(argv[i], "--pedantic"))) {
3057 xmlGetWarningsDefaultValue = 1;
3058 xmlPedanticParserDefault(1);
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003059 options |= XML_PARSE_PEDANTIC;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003060 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00003061#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003062 else if ((!strcmp(argv[i], "-debugent")) ||
3063 (!strcmp(argv[i], "--debugent"))) {
3064 debugent++;
3065 xmlParserDebugEntities = 1;
3066 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00003067#endif
Daniel Veillard25048d82004-08-14 22:37:54 +00003068#ifdef LIBXML_C14N_ENABLED
3069 else if ((!strcmp(argv[i], "-c14n")) ||
3070 (!strcmp(argv[i], "--c14n"))) {
3071 canonical++;
3072 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
3073 }
Aleksey Sanin2650df12005-06-06 17:16:50 +00003074 else if ((!strcmp(argv[i], "-exc-c14n")) ||
3075 (!strcmp(argv[i], "--exc-c14n"))) {
3076 exc_canonical++;
3077 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
3078 }
Daniel Veillard25048d82004-08-14 22:37:54 +00003079#endif
Daniel Veillard81418e32001-05-22 15:08:55 +00003080#ifdef LIBXML_CATALOG_ENABLED
3081 else if ((!strcmp(argv[i], "-catalogs")) ||
3082 (!strcmp(argv[i], "--catalogs"))) {
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003083 catalogs++;
3084 } else if ((!strcmp(argv[i], "-nocatalogs")) ||
3085 (!strcmp(argv[i], "--nocatalogs"))) {
3086 nocatalogs++;
Daniel Veillard81418e32001-05-22 15:08:55 +00003087 }
3088#endif
Daniel Veillardbe803962000-06-28 23:40:59 +00003089 else if ((!strcmp(argv[i], "-encode")) ||
3090 (!strcmp(argv[i], "--encode"))) {
3091 i++;
3092 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003093 /*
3094 * OK it's for testing purposes
3095 */
3096 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +00003097 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003098 else if ((!strcmp(argv[i], "-noblanks")) ||
3099 (!strcmp(argv[i], "--noblanks"))) {
3100 noblanks++;
3101 xmlKeepBlanksDefault(0);
Daniel Veillard90493a92001-08-14 14:12:47 +00003102 }
Daniel Veillard87076042004-05-03 22:54:49 +00003103 else if ((!strcmp(argv[i], "-maxmem")) ||
3104 (!strcmp(argv[i], "--maxmem"))) {
3105 i++;
3106 if (sscanf(argv[i], "%d", &maxmem) == 1) {
3107 xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc,
3108 myStrdupFunc);
3109 } else {
3110 maxmem = 0;
3111 }
3112 }
Daniel Veillard90493a92001-08-14 14:12:47 +00003113 else if ((!strcmp(argv[i], "-format")) ||
3114 (!strcmp(argv[i], "--format"))) {
3115 noblanks++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003116#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard90493a92001-08-14 14:12:47 +00003117 format++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003118#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard90493a92001-08-14 14:12:47 +00003119 xmlKeepBlanksDefault(0);
Daniel Veillard7704fb12003-01-03 16:19:51 +00003120 }
Daniel Veillard81273902003-09-30 00:43:48 +00003121#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003122 else if ((!strcmp(argv[i], "-stream")) ||
3123 (!strcmp(argv[i], "--stream"))) {
3124 stream++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003125 }
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003126 else if ((!strcmp(argv[i], "-walker")) ||
3127 (!strcmp(argv[i], "--walker"))) {
3128 walker++;
3129 noout++;
3130 }
Daniel Veillard81273902003-09-30 00:43:48 +00003131#endif /* LIBXML_READER_ENABLED */
3132#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +00003133 else if ((!strcmp(argv[i], "-sax1")) ||
3134 (!strcmp(argv[i], "--sax1"))) {
3135 sax1++;
3136 }
Daniel Veillard81273902003-09-30 00:43:48 +00003137#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003138 else if ((!strcmp(argv[i], "-sax")) ||
3139 (!strcmp(argv[i], "--sax"))) {
3140 sax++;
3141 }
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003142 else if ((!strcmp(argv[i], "-chkregister")) ||
3143 (!strcmp(argv[i], "--chkregister"))) {
3144 chkregister++;
Daniel Veillard71531f32003-02-05 13:19:53 +00003145#ifdef LIBXML_SCHEMAS_ENABLED
3146 } else if ((!strcmp(argv[i], "-relaxng")) ||
3147 (!strcmp(argv[i], "--relaxng"))) {
3148 i++;
3149 relaxng = argv[i];
3150 noent++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003151 options |= XML_PARSE_NOENT;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003152 } else if ((!strcmp(argv[i], "-schema")) ||
3153 (!strcmp(argv[i], "--schema"))) {
3154 i++;
3155 schema = argv[i];
3156 noent++;
Daniel Veillard71531f32003-02-05 13:19:53 +00003157#endif
Daniel Veillardd4501d72005-07-24 14:27:16 +00003158#ifdef LIBXML_SCHEMATRON_ENABLED
3159 } else if ((!strcmp(argv[i], "-schematron")) ||
3160 (!strcmp(argv[i], "--schematron"))) {
3161 i++;
3162 schematron = argv[i];
3163 noent++;
3164#endif
Daniel Veillarde8b09e42003-05-13 22:14:13 +00003165 } else if ((!strcmp(argv[i], "-nonet")) ||
3166 (!strcmp(argv[i], "--nonet"))) {
Daniel Veillard61b93382003-11-03 14:28:31 +00003167 options |= XML_PARSE_NONET;
Daniel Veillard968d6432006-04-25 16:17:53 +00003168 xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
Daniel Veillard8874b942005-08-25 13:19:21 +00003169 } else if ((!strcmp(argv[i], "-nocompact")) ||
3170 (!strcmp(argv[i], "--nocompact"))) {
3171 options &= ~XML_PARSE_COMPACT;
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003172 } else if ((!strcmp(argv[i], "-load-trace")) ||
3173 (!strcmp(argv[i], "--load-trace"))) {
3174 load_trace++;
3175 } else if ((!strcmp(argv[i], "-path")) ||
3176 (!strcmp(argv[i], "--path"))) {
3177 i++;
3178 parsePath(BAD_CAST argv[i]);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003179#ifdef LIBXML_PATTERN_ENABLED
3180 } else if ((!strcmp(argv[i], "-pattern")) ||
3181 (!strcmp(argv[i], "--pattern"))) {
3182 i++;
3183 pattern = argv[i];
3184#endif
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003185 } else {
3186 fprintf(stderr, "Unknown option %s\n", argv[i]);
3187 usage(argv[0]);
3188 return(1);
3189 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003190 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003191
3192#ifdef LIBXML_CATALOG_ENABLED
3193 if (nocatalogs == 0) {
3194 if (catalogs) {
3195 const char *catal;
3196
3197 catal = getenv("SGML_CATALOG_FILES");
Daniel Veillard6c5f9d12001-08-25 13:33:14 +00003198 if (catal != NULL) {
3199 xmlLoadCatalogs(catal);
3200 } else {
3201 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
3202 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003203 }
3204 }
3205#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003206
Daniel Veillard81273902003-09-30 00:43:48 +00003207#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +00003208 if (sax1)
3209 xmlSAXDefaultVersion(1);
3210 else
3211 xmlSAXDefaultVersion(2);
Daniel Veillard81273902003-09-30 00:43:48 +00003212#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillard07cb8222003-09-10 10:51:05 +00003213
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003214 if (chkregister) {
3215 xmlRegisterNodeDefault(registerNode);
3216 xmlDeregisterNodeDefault(deregisterNode);
3217 }
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00003218
3219 indent = getenv("XMLLINT_INDENT");
3220 if(indent != NULL) {
3221 xmlTreeIndentString = indent;
3222 }
3223
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003224
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003225 defaultEntityLoader = xmlGetExternalEntityLoader();
3226 xmlSetExternalEntityLoader(xmllintExternalEntityLoader);
3227
Daniel Veillardd9bad132001-07-23 19:39:43 +00003228 xmlLineNumbersDefault(1);
Daniel Veillard48da9102001-08-07 01:10:10 +00003229 if (loaddtd != 0)
3230 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
3231 if (dtdattrs)
3232 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003233 if (noent != 0) xmlSubstituteEntitiesDefault(1);
Daniel Veillard4432df22003-09-28 18:58:27 +00003234#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003235 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
Daniel Veillard4432df22003-09-28 18:58:27 +00003236#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003237 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003238 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003239 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003240 xmlGenericError(xmlGenericErrorContext,
3241 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
3242 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003243 "<html><head><title>%s output</title></head>\n",
3244 argv[0]);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003245 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003246 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
3247 argv[0]);
3248 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003249
Daniel Veillardd4501d72005-07-24 14:27:16 +00003250#ifdef LIBXML_SCHEMATRON_ENABLED
3251 if ((schematron != NULL) && (sax == 0)
3252#ifdef LIBXML_READER_ENABLED
3253 && (stream == 0)
3254#endif /* LIBXML_READER_ENABLED */
3255 ) {
3256 xmlSchematronParserCtxtPtr ctxt;
3257
3258 /* forces loading the DTDs */
3259 xmlLoadExtDtdDefaultValue |= 1;
3260 options |= XML_PARSE_DTDLOAD;
3261 if (timing) {
3262 startTimer();
3263 }
3264 ctxt = xmlSchematronNewParserCtxt(schematron);
3265#if 0
3266 xmlSchematronSetParserErrors(ctxt,
3267 (xmlSchematronValidityErrorFunc) fprintf,
3268 (xmlSchematronValidityWarningFunc) fprintf,
3269 stderr);
3270#endif
3271 wxschematron = xmlSchematronParse(ctxt);
3272 if (wxschematron == NULL) {
3273 xmlGenericError(xmlGenericErrorContext,
3274 "Schematron schema %s failed to compile\n", schematron);
3275 progresult = XMLLINT_ERR_SCHEMACOMP;
3276 schematron = NULL;
3277 }
3278 xmlSchematronFreeParserCtxt(ctxt);
3279 if (timing) {
3280 endTimer("Compiling the schemas");
3281 }
3282 }
3283#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00003284#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003285 if ((relaxng != NULL) && (sax == 0)
Daniel Veillard81273902003-09-30 00:43:48 +00003286#ifdef LIBXML_READER_ENABLED
3287 && (stream == 0)
3288#endif /* LIBXML_READER_ENABLED */
3289 ) {
Daniel Veillard71531f32003-02-05 13:19:53 +00003290 xmlRelaxNGParserCtxtPtr ctxt;
3291
Daniel Veillardce192eb2003-04-16 15:58:05 +00003292 /* forces loading the DTDs */
3293 xmlLoadExtDtdDefaultValue |= 1;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003294 options |= XML_PARSE_DTDLOAD;
Daniel Veillard42f12e92003-03-07 18:32:59 +00003295 if (timing) {
3296 startTimer();
3297 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003298 ctxt = xmlRelaxNGNewParserCtxt(relaxng);
3299 xmlRelaxNGSetParserErrors(ctxt,
3300 (xmlRelaxNGValidityErrorFunc) fprintf,
3301 (xmlRelaxNGValidityWarningFunc) fprintf,
3302 stderr);
3303 relaxngschemas = xmlRelaxNGParse(ctxt);
Daniel Veillardce192eb2003-04-16 15:58:05 +00003304 if (relaxngschemas == NULL) {
3305 xmlGenericError(xmlGenericErrorContext,
3306 "Relax-NG schema %s failed to compile\n", relaxng);
William M. Brack8304d872004-06-08 13:29:32 +00003307 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillardce192eb2003-04-16 15:58:05 +00003308 relaxng = NULL;
3309 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003310 xmlRelaxNGFreeParserCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00003311 if (timing) {
3312 endTimer("Compiling the schemas");
3313 }
Daniel Veillardebe25d42004-03-25 09:35:49 +00003314 } else if ((schema != NULL)
3315#ifdef LIBXML_READER_ENABLED
Daniel Veillardf10ae122005-07-10 19:03:16 +00003316 && (stream == 0)
Daniel Veillardebe25d42004-03-25 09:35:49 +00003317#endif
3318 ) {
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003319 xmlSchemaParserCtxtPtr ctxt;
3320
3321 if (timing) {
3322 startTimer();
3323 }
3324 ctxt = xmlSchemaNewParserCtxt(schema);
3325 xmlSchemaSetParserErrors(ctxt,
3326 (xmlSchemaValidityErrorFunc) fprintf,
3327 (xmlSchemaValidityWarningFunc) fprintf,
3328 stderr);
3329 wxschemas = xmlSchemaParse(ctxt);
3330 if (wxschemas == NULL) {
3331 xmlGenericError(xmlGenericErrorContext,
3332 "WXS schema %s failed to compile\n", schema);
William M. Brack8304d872004-06-08 13:29:32 +00003333 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003334 schema = NULL;
3335 }
3336 xmlSchemaFreeParserCtxt(ctxt);
3337 if (timing) {
3338 endTimer("Compiling the schemas");
3339 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003340 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003341#endif /* LIBXML_SCHEMAS_ENABLED */
3342#ifdef LIBXML_PATTERN_ENABLED
Daniel Veillard39e5c892005-07-03 22:48:50 +00003343 if ((pattern != NULL)
Daniel Veillardc9352532005-07-04 14:25:34 +00003344#ifdef LIBXML_READER_ENABLED
Daniel Veillard39e5c892005-07-03 22:48:50 +00003345 && (walker == 0)
3346#endif
3347 ) {
Daniel Veillardffa7b7e2003-12-05 16:10:21 +00003348 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003349 if (patternc == NULL) {
3350 xmlGenericError(xmlGenericErrorContext,
3351 "Pattern %s failed to compile\n", pattern);
William M. Brack8304d872004-06-08 13:29:32 +00003352 progresult = XMLLINT_ERR_SCHEMAPAT;
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003353 pattern = NULL;
3354 }
3355 }
3356#endif /* LIBXML_PATTERN_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003357 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +00003358 if ((!strcmp(argv[i], "-encode")) ||
3359 (!strcmp(argv[i], "--encode"))) {
3360 i++;
3361 continue;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003362 } else if ((!strcmp(argv[i], "-o")) ||
3363 (!strcmp(argv[i], "-output")) ||
3364 (!strcmp(argv[i], "--output"))) {
3365 i++;
3366 continue;
Daniel Veillardbe803962000-06-28 23:40:59 +00003367 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003368#ifdef LIBXML_VALID_ENABLED
Daniel Veillardcd429612000-10-11 15:57:05 +00003369 if ((!strcmp(argv[i], "-dtdvalid")) ||
3370 (!strcmp(argv[i], "--dtdvalid"))) {
3371 i++;
3372 continue;
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003373 }
3374 if ((!strcmp(argv[i], "-path")) ||
3375 (!strcmp(argv[i], "--path"))) {
3376 i++;
3377 continue;
Daniel Veillardcd429612000-10-11 15:57:05 +00003378 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00003379 if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3380 (!strcmp(argv[i], "--dtdvalidfpi"))) {
3381 i++;
3382 continue;
3383 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003384#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard71531f32003-02-05 13:19:53 +00003385 if ((!strcmp(argv[i], "-relaxng")) ||
3386 (!strcmp(argv[i], "--relaxng"))) {
3387 i++;
3388 continue;
3389 }
Daniel Veillard87076042004-05-03 22:54:49 +00003390 if ((!strcmp(argv[i], "-maxmem")) ||
3391 (!strcmp(argv[i], "--maxmem"))) {
3392 i++;
3393 continue;
3394 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003395 if ((!strcmp(argv[i], "-schema")) ||
3396 (!strcmp(argv[i], "--schema"))) {
3397 i++;
3398 continue;
3399 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00003400 if ((!strcmp(argv[i], "-schematron")) ||
3401 (!strcmp(argv[i], "--schematron"))) {
3402 i++;
3403 continue;
3404 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003405#ifdef LIBXML_PATTERN_ENABLED
3406 if ((!strcmp(argv[i], "-pattern")) ||
3407 (!strcmp(argv[i], "--pattern"))) {
3408 i++;
3409 continue;
3410 }
3411#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00003412 if ((timing) && (repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00003413 startTimer();
Daniel Veillardcbaf3992001-12-31 16:16:02 +00003414 /* Remember file names. "-" means stdin. <sven@zen.org> */
Daniel Veillard4a6845d2001-01-03 13:32:39 +00003415 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003416 if (repeat) {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003417 xmlParserCtxtPtr ctxt = NULL;
3418
3419 for (acount = 0;acount < repeat;acount++) {
Daniel Veillard81273902003-09-30 00:43:48 +00003420#ifdef LIBXML_READER_ENABLED
Daniel Veillard198c1bf2003-10-20 17:07:41 +00003421 if (stream != 0) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00003422 streamFile(argv[i]);
Daniel Veillard198c1bf2003-10-20 17:07:41 +00003423 } else {
Daniel Veillard81273902003-09-30 00:43:48 +00003424#endif /* LIBXML_READER_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003425 if (sax) {
3426 testSAX(argv[i]);
3427 } else {
3428 if (ctxt == NULL)
3429 ctxt = xmlNewParserCtxt();
3430 parseAndPrintFile(argv[i], ctxt);
3431 }
Daniel Veillard81273902003-09-30 00:43:48 +00003432#ifdef LIBXML_READER_ENABLED
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003433 }
Daniel Veillard81273902003-09-30 00:43:48 +00003434#endif /* LIBXML_READER_ENABLED */
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003435 }
3436 if (ctxt != NULL)
3437 xmlFreeParserCtxt(ctxt);
Daniel Veillard7704fb12003-01-03 16:19:51 +00003438 } else {
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003439 nbregister = 0;
3440
Daniel Veillard81273902003-09-30 00:43:48 +00003441#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003442 if (stream != 0)
3443 streamFile(argv[i]);
3444 else
Daniel Veillard81273902003-09-30 00:43:48 +00003445#endif /* LIBXML_READER_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003446 if (sax) {
3447 testSAX(argv[i]);
3448 } else {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003449 parseAndPrintFile(argv[i], NULL);
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003450 }
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003451
3452 if ((chkregister) && (nbregister != 0)) {
3453 fprintf(stderr, "Registration count off: %d\n", nbregister);
William M. Brack8304d872004-06-08 13:29:32 +00003454 progresult = XMLLINT_ERR_RDREGIS;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003455 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00003456 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003457 files ++;
Daniel Veillarda7866932001-12-04 13:14:44 +00003458 if ((timing) && (repeat)) {
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00003459 endTimer("%d iterations", repeat);
Daniel Veillarda7866932001-12-04 13:14:44 +00003460 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00003461 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003462 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00003463 if (generate)
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003464 parseAndPrintFile(NULL, NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003465 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003466 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003467 }
Daniel Veillard845cce42002-01-09 11:51:37 +00003468 if ((files == 0) && (!generate) && (version == 0)) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003469 usage(argv[0]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003470 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00003471#ifdef LIBXML_SCHEMATRON_ENABLED
3472 if (wxschematron != NULL)
3473 xmlSchematronFree(wxschematron);
3474#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00003475#ifdef LIBXML_SCHEMAS_ENABLED
3476 if (relaxngschemas != NULL)
3477 xmlRelaxNGFree(relaxngschemas);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003478 if (wxschemas != NULL)
3479 xmlSchemaFree(wxschemas);
Daniel Veillard71531f32003-02-05 13:19:53 +00003480 xmlRelaxNGCleanupTypes();
3481#endif
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003482#ifdef LIBXML_PATTERN_ENABLED
3483 if (patternc != NULL)
3484 xmlFreePattern(patternc);
3485#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003486 xmlCleanupParser();
3487 xmlMemoryDump();
3488
Daniel Veillardf7cd4812001-02-23 18:44:52 +00003489 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003490}
Daniel Veillard88a172f2000-08-04 18:23:10 +00003491