blob: 607cea3173ab173de200cf4df01371fa84260a06 [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 Veillardd4501d72005-07-24 14:27:16 +0000149#ifdef LIBXML_SCHEMAS_ENABLED
150static 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;
245
246 int i;
247 const char *lastsegment = URL;
248 const char *iter = URL;
249
250 if (nbpaths > 0) {
251 while (*iter != 0) {
252 if (*iter == '/')
253 lastsegment = iter + 1;
254 iter++;
255 }
256 }
257
258 if ((ctxt != NULL) && (ctxt->sax != NULL)) {
259 warning = ctxt->sax->warning;
260 ctxt->sax->warning = NULL;
261 }
262
263 if (defaultEntityLoader != NULL) {
264 ret = defaultEntityLoader(URL, ID, ctxt);
265 if (ret != NULL) {
266 if (warning != NULL)
267 ctxt->sax->warning = warning;
268 if (load_trace) {
269 fprintf \
270 (stderr,
271 "Loaded URL=\"%s\" ID=\"%s\"\n",
272 URL ? URL : "(null)",
273 ID ? ID : "(null)");
274 }
275 return(ret);
276 }
277 }
278 for (i = 0;i < nbpaths;i++) {
279 xmlChar *newURL;
280
281 newURL = xmlStrdup((const xmlChar *) paths[i]);
282 newURL = xmlStrcat(newURL, (const xmlChar *) "/");
283 newURL = xmlStrcat(newURL, (const xmlChar *) lastsegment);
284 if (newURL != NULL) {
285 ret = defaultEntityLoader((const char *)newURL, ID, ctxt);
286 if (ret != NULL) {
287 if (warning != NULL)
288 ctxt->sax->warning = warning;
289 if (load_trace) {
290 fprintf \
291 (stderr,
292 "Loaded URL=\"%s\" ID=\"%s\"\n",
293 newURL,
294 ID ? ID : "(null)");
295 }
296 xmlFree(newURL);
297 return(ret);
298 }
299 xmlFree(newURL);
300 }
301 }
302 if (warning != NULL) {
303 ctxt->sax->warning = warning;
304 if (URL != NULL)
305 warning(ctxt, "failed to load external entity \"%s\"\n", URL);
306 else if (ID != NULL)
307 warning(ctxt, "failed to load external entity \"%s\"\n", ID);
308 }
309 return(NULL);
310}
311/************************************************************************
Daniel Veillard87076042004-05-03 22:54:49 +0000312 * *
313 * Memory allocation consumption debugging *
314 * *
315 ************************************************************************/
316
Daniel Veillard3af3b592004-05-05 19:22:30 +0000317static void
318OOM(void)
319{
Daniel Veillard87076042004-05-03 22:54:49 +0000320 fprintf(stderr, "Ran out of memory needs > %d bytes\n", maxmem);
William M. Brack8304d872004-06-08 13:29:32 +0000321 progresult = XMLLINT_ERR_MEM;
Daniel Veillard87076042004-05-03 22:54:49 +0000322}
323
Daniel Veillard3af3b592004-05-05 19:22:30 +0000324static void
325myFreeFunc(void *mem)
326{
Daniel Veillard87076042004-05-03 22:54:49 +0000327 xmlMemFree(mem);
328}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000329static void *
330myMallocFunc(size_t size)
331{
Daniel Veillard87076042004-05-03 22:54:49 +0000332 void *ret;
333
334 ret = xmlMemMalloc(size);
335 if (ret != NULL) {
336 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000337 OOM();
338 xmlMemFree(ret);
339 return (NULL);
340 }
Daniel Veillard87076042004-05-03 22:54:49 +0000341 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000342 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000343}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000344static void *
345myReallocFunc(void *mem, size_t size)
346{
Daniel Veillard87076042004-05-03 22:54:49 +0000347 void *ret;
348
349 ret = xmlMemRealloc(mem, size);
350 if (ret != NULL) {
351 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000352 OOM();
353 xmlMemFree(ret);
354 return (NULL);
355 }
Daniel Veillard87076042004-05-03 22:54:49 +0000356 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000357 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000358}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000359static char *
360myStrdupFunc(const char *str)
361{
Daniel Veillard87076042004-05-03 22:54:49 +0000362 char *ret;
363
364 ret = xmlMemoryStrdup(str);
365 if (ret != NULL) {
366 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000367 OOM();
368 xmlFree(ret);
369 return (NULL);
370 }
Daniel Veillard87076042004-05-03 22:54:49 +0000371 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000372 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000373}
Daniel Veillard87076042004-05-03 22:54:49 +0000374/************************************************************************
375 * *
376 * Internal timing routines to remove the necessity to have *
377 * unix-specific function calls. *
378 * *
379 ************************************************************************/
Daniel Veillard01db67c2001-12-18 07:09:59 +0000380
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000381#ifndef HAVE_GETTIMEOFDAY
382#ifdef HAVE_SYS_TIMEB_H
383#ifdef HAVE_SYS_TIME_H
384#ifdef HAVE_FTIME
385
Daniel Veillard01c13b52002-12-10 15:19:08 +0000386static int
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000387my_gettimeofday(struct timeval *tvp, void *tzp)
388{
389 struct timeb timebuffer;
390
391 ftime(&timebuffer);
392 if (tvp) {
393 tvp->tv_sec = timebuffer.time;
394 tvp->tv_usec = timebuffer.millitm * 1000L;
395 }
396 return (0);
397}
398#define HAVE_GETTIMEOFDAY 1
399#define gettimeofday my_gettimeofday
400
401#endif /* HAVE_FTIME */
402#endif /* HAVE_SYS_TIME_H */
403#endif /* HAVE_SYS_TIMEB_H */
404#endif /* !HAVE_GETTIMEOFDAY */
405
Daniel Veillard01db67c2001-12-18 07:09:59 +0000406#if defined(HAVE_GETTIMEOFDAY)
407static struct timeval begin, end;
408
409/*
410 * startTimer: call where you want to start timing
411 */
412static void
413startTimer(void)
414{
415 gettimeofday(&begin, NULL);
416}
417
418/*
419 * endTimer: call where you want to stop timing and to print out a
420 * message about the timing performed; format is a printf
421 * type argument
422 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000423static void XMLCDECL
Daniel Veillard118aed72002-09-24 14:13:13 +0000424endTimer(const char *fmt, ...)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000425{
426 long msec;
427 va_list ap;
428
429 gettimeofday(&end, NULL);
430 msec = end.tv_sec - begin.tv_sec;
431 msec *= 1000;
432 msec += (end.tv_usec - begin.tv_usec) / 1000;
433
434#ifndef HAVE_STDARG_H
435#error "endTimer required stdarg functions"
436#endif
Daniel Veillard118aed72002-09-24 14:13:13 +0000437 va_start(ap, fmt);
438 vfprintf(stderr, fmt, ap);
Daniel Veillard01db67c2001-12-18 07:09:59 +0000439 va_end(ap);
440
441 fprintf(stderr, " took %ld ms\n", msec);
442}
443#elif defined(HAVE_TIME_H)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000444/*
445 * No gettimeofday function, so we have to make do with calling clock.
446 * This is obviously less accurate, but there's little we can do about
447 * that.
448 */
Daniel Veillard90bc3712002-03-07 15:12:58 +0000449#ifndef CLOCKS_PER_SEC
450#define CLOCKS_PER_SEC 100
451#endif
Daniel Veillard01db67c2001-12-18 07:09:59 +0000452
453static clock_t begin, end;
454static void
455startTimer(void)
456{
457 begin = clock();
458}
Daniel Veillardffa3c742005-07-21 13:24:09 +0000459static void XMLCDECL
Daniel Veillard01db67c2001-12-18 07:09:59 +0000460endTimer(const char *fmt, ...)
461{
462 long msec;
463 va_list ap;
464
465 end = clock();
466 msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
467
468#ifndef HAVE_STDARG_H
469#error "endTimer required stdarg functions"
470#endif
471 va_start(ap, fmt);
472 vfprintf(stderr, fmt, ap);
473 va_end(ap);
474 fprintf(stderr, " took %ld ms\n", msec);
475}
476#else
477
478/*
479 * We don't have a gettimeofday or time.h, so we just don't do timing
480 */
481static void
482startTimer(void)
483{
484 /*
485 * Do nothing
486 */
487}
Daniel Veillardffa3c742005-07-21 13:24:09 +0000488static void XMLCDECL
Daniel Veillard01db67c2001-12-18 07:09:59 +0000489endTimer(char *format, ...)
490{
491 /*
492 * We cannot do anything because we don't have a timing function
493 */
494#ifdef HAVE_STDARG_H
495 va_start(ap, format);
496 vfprintf(stderr, format, ap);
497 va_end(ap);
498 fprintf(stderr, " was not timed\n", msec);
499#else
500 /* We don't have gettimeofday, time or stdarg.h, what crazy world is
501 * this ?!
502 */
503#endif
504}
505#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000506/************************************************************************
507 * *
508 * HTML ouput *
509 * *
510 ************************************************************************/
Daniel Veillard24505b02005-07-28 23:49:35 +0000511static char buffer[50000];
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000512
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000513static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000514xmlHTMLEncodeSend(void) {
515 char *result;
516
517 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
518 if (result) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000519 xmlGenericError(xmlGenericErrorContext, "%s", result);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000520 xmlFree(result);
521 }
522 buffer[0] = 0;
523}
524
525/**
526 * xmlHTMLPrintFileInfo:
527 * @input: an xmlParserInputPtr input
528 *
529 * Displays the associated file and line informations for the current input
530 */
531
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000532static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000533xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000534 int len;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000535 xmlGenericError(xmlGenericErrorContext, "<p>");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000536
537 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000538 if (input != NULL) {
539 if (input->filename) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000540 snprintf(&buffer[len], sizeof(buffer) - len, "%s:%d: ", input->filename,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000541 input->line);
542 } else {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000543 snprintf(&buffer[len], sizeof(buffer) - len, "Entity: line %d: ", input->line);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000544 }
545 }
546 xmlHTMLEncodeSend();
547}
548
549/**
550 * xmlHTMLPrintFileContext:
551 * @input: an xmlParserInputPtr input
552 *
553 * Displays current context within the input content for error tracking
554 */
555
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000556static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000557xmlHTMLPrintFileContext(xmlParserInputPtr input) {
558 const xmlChar *cur, *base;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000559 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000560 int n;
561
562 if (input == NULL) return;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000563 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000564 cur = input->cur;
565 base = input->base;
566 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
567 cur--;
568 }
569 n = 0;
570 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
571 cur--;
572 if ((*cur == '\n') || (*cur == '\r')) cur++;
573 base = cur;
574 n = 0;
575 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000576 len = strlen(buffer);
577 snprintf(&buffer[len], sizeof(buffer) - len, "%c",
578 (unsigned char) *cur++);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000579 n++;
580 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000581 len = strlen(buffer);
582 snprintf(&buffer[len], sizeof(buffer) - len, "\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000583 cur = input->cur;
584 while ((*cur == '\n') || (*cur == '\r'))
585 cur--;
586 n = 0;
587 while ((cur != base) && (n++ < 80)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000588 len = strlen(buffer);
589 snprintf(&buffer[len], sizeof(buffer) - len, " ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000590 base++;
591 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000592 len = strlen(buffer);
593 snprintf(&buffer[len], sizeof(buffer) - len, "^\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000594 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000595 xmlGenericError(xmlGenericErrorContext, "</pre>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000596}
597
598/**
599 * xmlHTMLError:
600 * @ctx: an XML parser context
601 * @msg: the message to display/transmit
602 * @...: extra parameters for the message display
603 *
604 * Display and format an error messages, gives file, line, position and
605 * extra parameters.
606 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000607static void XMLCDECL
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000608xmlHTMLError(void *ctx, const char *msg, ...)
609{
610 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
611 xmlParserInputPtr input;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000612 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000613 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000614
615 buffer[0] = 0;
616 input = ctxt->input;
617 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000618 input = ctxt->inputTab[ctxt->inputNr - 2];
619 }
620
621 xmlHTMLPrintFileInfo(input);
622
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000623 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000624 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000625 len = strlen(buffer);
626 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000627 va_end(args);
628 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000629 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000630
631 xmlHTMLPrintFileContext(input);
632 xmlHTMLEncodeSend();
633}
634
635/**
636 * xmlHTMLWarning:
637 * @ctx: an XML parser context
638 * @msg: the message to display/transmit
639 * @...: extra parameters for the message display
640 *
641 * Display and format a warning messages, gives file, line, position and
642 * extra parameters.
643 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000644static void XMLCDECL
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000645xmlHTMLWarning(void *ctx, const char *msg, ...)
646{
647 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
648 xmlParserInputPtr input;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000649 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000650 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000651
652 buffer[0] = 0;
653 input = ctxt->input;
654 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000655 input = ctxt->inputTab[ctxt->inputNr - 2];
656 }
657
658
659 xmlHTMLPrintFileInfo(input);
660
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000661 xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000662 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000663 len = strlen(buffer);
664 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000665 va_end(args);
666 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000667 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000668
669 xmlHTMLPrintFileContext(input);
670 xmlHTMLEncodeSend();
671}
672
673/**
674 * xmlHTMLValidityError:
675 * @ctx: an XML parser context
676 * @msg: the message to display/transmit
677 * @...: extra parameters for the message display
678 *
679 * Display and format an validity error messages, gives file,
680 * line, position and extra parameters.
681 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000682static void XMLCDECL
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000683xmlHTMLValidityError(void *ctx, const char *msg, ...)
684{
685 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
686 xmlParserInputPtr input;
687 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000688 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000689
690 buffer[0] = 0;
691 input = ctxt->input;
692 if ((input->filename == NULL) && (ctxt->inputNr > 1))
693 input = ctxt->inputTab[ctxt->inputNr - 2];
694
695 xmlHTMLPrintFileInfo(input);
696
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000697 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000698 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000699 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000700 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000701 va_end(args);
702 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000703 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000704
705 xmlHTMLPrintFileContext(input);
706 xmlHTMLEncodeSend();
Daniel Veillard9fcb4912005-03-16 12:57:31 +0000707 progresult = XMLLINT_ERR_VALID;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000708}
709
710/**
711 * xmlHTMLValidityWarning:
712 * @ctx: an XML parser context
713 * @msg: the message to display/transmit
714 * @...: extra parameters for the message display
715 *
716 * Display and format a validity warning messages, gives file, line,
717 * position and extra parameters.
718 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000719static void XMLCDECL
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000720xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
721{
722 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
723 xmlParserInputPtr input;
724 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000725 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000726
727 buffer[0] = 0;
728 input = ctxt->input;
729 if ((input->filename == NULL) && (ctxt->inputNr > 1))
730 input = ctxt->inputTab[ctxt->inputNr - 2];
731
732 xmlHTMLPrintFileInfo(input);
733
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000734 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000735 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000736 len = strlen(buffer);
737 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000738 va_end(args);
739 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000740 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000741
742 xmlHTMLPrintFileContext(input);
743 xmlHTMLEncodeSend();
744}
745
746/************************************************************************
747 * *
748 * Shell Interface *
749 * *
750 ************************************************************************/
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000751#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000752#ifdef LIBXML_XPATH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000753/**
754 * xmlShellReadline:
755 * @prompt: the prompt value
756 *
757 * Read a string
758 *
759 * Returns a pointer to it or NULL on EOF the caller is expected to
760 * free the returned string.
761 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000762static char *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000763xmlShellReadline(char *prompt) {
764#ifdef HAVE_LIBREADLINE
765 char *line_read;
766
767 /* Get a line from the user. */
768 line_read = readline (prompt);
769
770 /* If the line has any text in it, save it on the history. */
771 if (line_read && *line_read)
772 add_history (line_read);
773
774 return (line_read);
775#else
776 char line_read[501];
Daniel Veillard29e43992001-12-13 22:21:58 +0000777 char *ret;
778 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000779
780 if (prompt != NULL)
781 fprintf(stdout, "%s", prompt);
782 if (!fgets(line_read, 500, stdin))
783 return(NULL);
784 line_read[500] = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000785 len = strlen(line_read);
786 ret = (char *) malloc(len + 1);
787 if (ret != NULL) {
788 memcpy (ret, line_read, len + 1);
789 }
790 return(ret);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000791#endif
792}
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000793#endif /* LIBXML_XPATH_ENABLED */
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000794#endif /* LIBXML_DEBUG_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000795
796/************************************************************************
797 * *
Daniel Veillard5e873c42000-04-12 13:27:38 +0000798 * I/O Interfaces *
799 * *
800 ************************************************************************/
801
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000802static int myRead(FILE *f, char * buf, int len) {
803 return(fread(buf, 1, len, f));
Daniel Veillard5e873c42000-04-12 13:27:38 +0000804}
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000805static void myClose(FILE *f) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000806 if (f != stdin) {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000807 fclose(f);
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000808 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000809}
810
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000811/************************************************************************
812 * *
813 * SAX based tests *
814 * *
815 ************************************************************************/
816
817/*
818 * empty SAX block
819 */
Daniel Veillard24505b02005-07-28 23:49:35 +0000820static xmlSAXHandler emptySAXHandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000821 NULL, /* internalSubset */
822 NULL, /* isStandalone */
823 NULL, /* hasInternalSubset */
824 NULL, /* hasExternalSubset */
825 NULL, /* resolveEntity */
826 NULL, /* getEntity */
827 NULL, /* entityDecl */
828 NULL, /* notationDecl */
829 NULL, /* attributeDecl */
830 NULL, /* elementDecl */
831 NULL, /* unparsedEntityDecl */
832 NULL, /* setDocumentLocator */
833 NULL, /* startDocument */
834 NULL, /* endDocument */
835 NULL, /* startElement */
836 NULL, /* endElement */
837 NULL, /* reference */
838 NULL, /* characters */
839 NULL, /* ignorableWhitespace */
840 NULL, /* processingInstruction */
841 NULL, /* comment */
842 NULL, /* xmlParserWarning */
843 NULL, /* xmlParserError */
844 NULL, /* xmlParserError */
845 NULL, /* getParameterEntity */
846 NULL, /* cdataBlock; */
847 NULL, /* externalSubset; */
Daniel Veillard971771e2005-07-09 17:32:57 +0000848 XML_SAX2_MAGIC,
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000849 NULL,
850 NULL, /* startElementNs */
851 NULL, /* endElementNs */
852 NULL /* xmlStructuredErrorFunc */
853};
854
Daniel Veillard24505b02005-07-28 23:49:35 +0000855static xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000856extern xmlSAXHandlerPtr debugSAXHandler;
857static int callbacks;
858
859/**
860 * isStandaloneDebug:
861 * @ctxt: An XML parser context
862 *
863 * Is this document tagged standalone ?
864 *
865 * Returns 1 if true
866 */
867static int
868isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
869{
870 callbacks++;
871 if (noout)
872 return(0);
873 fprintf(stdout, "SAX.isStandalone()\n");
874 return(0);
875}
876
877/**
878 * hasInternalSubsetDebug:
879 * @ctxt: An XML parser context
880 *
881 * Does this document has an internal subset
882 *
883 * Returns 1 if true
884 */
885static int
886hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
887{
888 callbacks++;
889 if (noout)
890 return(0);
891 fprintf(stdout, "SAX.hasInternalSubset()\n");
892 return(0);
893}
894
895/**
896 * hasExternalSubsetDebug:
897 * @ctxt: An XML parser context
898 *
899 * Does this document has an external subset
900 *
901 * Returns 1 if true
902 */
903static int
904hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
905{
906 callbacks++;
907 if (noout)
908 return(0);
909 fprintf(stdout, "SAX.hasExternalSubset()\n");
910 return(0);
911}
912
913/**
914 * internalSubsetDebug:
915 * @ctxt: An XML parser context
916 *
917 * Does this document has an internal subset
918 */
919static void
920internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
921 const xmlChar *ExternalID, const xmlChar *SystemID)
922{
923 callbacks++;
924 if (noout)
925 return;
926 fprintf(stdout, "SAX.internalSubset(%s,", name);
927 if (ExternalID == NULL)
928 fprintf(stdout, " ,");
929 else
930 fprintf(stdout, " %s,", ExternalID);
931 if (SystemID == NULL)
932 fprintf(stdout, " )\n");
933 else
934 fprintf(stdout, " %s)\n", SystemID);
935}
936
937/**
938 * externalSubsetDebug:
939 * @ctxt: An XML parser context
940 *
941 * Does this document has an external subset
942 */
943static void
944externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
945 const xmlChar *ExternalID, const xmlChar *SystemID)
946{
947 callbacks++;
948 if (noout)
949 return;
950 fprintf(stdout, "SAX.externalSubset(%s,", name);
951 if (ExternalID == NULL)
952 fprintf(stdout, " ,");
953 else
954 fprintf(stdout, " %s,", ExternalID);
955 if (SystemID == NULL)
956 fprintf(stdout, " )\n");
957 else
958 fprintf(stdout, " %s)\n", SystemID);
959}
960
961/**
962 * resolveEntityDebug:
963 * @ctxt: An XML parser context
964 * @publicId: The public ID of the entity
965 * @systemId: The system ID of the entity
966 *
967 * Special entity resolver, better left to the parser, it has
968 * more context than the application layer.
969 * The default behaviour is to NOT resolve the entities, in that case
970 * the ENTITY_REF nodes are built in the structure (and the parameter
971 * values).
972 *
973 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
974 */
975static xmlParserInputPtr
976resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
977{
978 callbacks++;
979 if (noout)
980 return(NULL);
981 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
982
983
984 fprintf(stdout, "SAX.resolveEntity(");
985 if (publicId != NULL)
986 fprintf(stdout, "%s", (char *)publicId);
987 else
988 fprintf(stdout, " ");
989 if (systemId != NULL)
990 fprintf(stdout, ", %s)\n", (char *)systemId);
991 else
992 fprintf(stdout, ", )\n");
993 return(NULL);
994}
995
996/**
997 * getEntityDebug:
998 * @ctxt: An XML parser context
999 * @name: The entity name
1000 *
1001 * Get an entity by name
1002 *
1003 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
1004 */
1005static xmlEntityPtr
1006getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1007{
1008 callbacks++;
1009 if (noout)
1010 return(NULL);
1011 fprintf(stdout, "SAX.getEntity(%s)\n", name);
1012 return(NULL);
1013}
1014
1015/**
1016 * getParameterEntityDebug:
1017 * @ctxt: An XML parser context
1018 * @name: The entity name
1019 *
1020 * Get a parameter entity by name
1021 *
1022 * Returns the xmlParserInputPtr
1023 */
1024static xmlEntityPtr
1025getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1026{
1027 callbacks++;
1028 if (noout)
1029 return(NULL);
1030 fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
1031 return(NULL);
1032}
1033
1034
1035/**
1036 * entityDeclDebug:
1037 * @ctxt: An XML parser context
1038 * @name: the entity name
1039 * @type: the entity type
1040 * @publicId: The public ID of the entity
1041 * @systemId: The system ID of the entity
1042 * @content: the entity value (without processing).
1043 *
1044 * An entity definition has been parsed
1045 */
1046static void
1047entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
1048 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
1049{
1050const xmlChar *nullstr = BAD_CAST "(null)";
1051 /* not all libraries handle printing null pointers nicely */
1052 if (publicId == NULL)
1053 publicId = nullstr;
1054 if (systemId == NULL)
1055 systemId = nullstr;
1056 if (content == NULL)
1057 content = (xmlChar *)nullstr;
1058 callbacks++;
1059 if (noout)
1060 return;
1061 fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
1062 name, type, publicId, systemId, content);
1063}
1064
1065/**
1066 * attributeDeclDebug:
1067 * @ctxt: An XML parser context
1068 * @name: the attribute name
1069 * @type: the attribute type
1070 *
1071 * An attribute definition has been parsed
1072 */
1073static void
1074attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar * elem,
1075 const xmlChar * name, int type, int def,
1076 const xmlChar * defaultValue, xmlEnumerationPtr tree)
1077{
1078 callbacks++;
1079 if (noout)
1080 return;
1081 if (defaultValue == NULL)
1082 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
1083 elem, name, type, def);
1084 else
1085 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
1086 elem, name, type, def, defaultValue);
1087 xmlFreeEnumeration(tree);
1088}
1089
1090/**
1091 * elementDeclDebug:
1092 * @ctxt: An XML parser context
1093 * @name: the element name
1094 * @type: the element type
1095 * @content: the element value (without processing).
1096 *
1097 * An element definition has been parsed
1098 */
1099static void
1100elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
1101 xmlElementContentPtr content ATTRIBUTE_UNUSED)
1102{
1103 callbacks++;
1104 if (noout)
1105 return;
1106 fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
1107 name, type);
1108}
1109
1110/**
1111 * notationDeclDebug:
1112 * @ctxt: An XML parser context
1113 * @name: The name of the notation
1114 * @publicId: The public ID of the entity
1115 * @systemId: The system ID of the entity
1116 *
1117 * What to do when a notation declaration has been parsed.
1118 */
1119static void
1120notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
1121 const xmlChar *publicId, const xmlChar *systemId)
1122{
1123 callbacks++;
1124 if (noout)
1125 return;
1126 fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
1127 (char *) name, (char *) publicId, (char *) systemId);
1128}
1129
1130/**
1131 * unparsedEntityDeclDebug:
1132 * @ctxt: An XML parser context
1133 * @name: The name of the entity
1134 * @publicId: The public ID of the entity
1135 * @systemId: The system ID of the entity
1136 * @notationName: the name of the notation
1137 *
1138 * What to do when an unparsed entity declaration is parsed
1139 */
1140static void
1141unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
1142 const xmlChar *publicId, const xmlChar *systemId,
1143 const xmlChar *notationName)
1144{
1145const xmlChar *nullstr = BAD_CAST "(null)";
1146
1147 if (publicId == NULL)
1148 publicId = nullstr;
1149 if (systemId == NULL)
1150 systemId = nullstr;
1151 if (notationName == NULL)
1152 notationName = nullstr;
1153 callbacks++;
1154 if (noout)
1155 return;
1156 fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
1157 (char *) name, (char *) publicId, (char *) systemId,
1158 (char *) notationName);
1159}
1160
1161/**
1162 * setDocumentLocatorDebug:
1163 * @ctxt: An XML parser context
1164 * @loc: A SAX Locator
1165 *
1166 * Receive the document locator at startup, actually xmlDefaultSAXLocator
1167 * Everything is available on the context, so this is useless in our case.
1168 */
1169static void
1170setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
1171{
1172 callbacks++;
1173 if (noout)
1174 return;
1175 fprintf(stdout, "SAX.setDocumentLocator()\n");
1176}
1177
1178/**
1179 * startDocumentDebug:
1180 * @ctxt: An XML parser context
1181 *
1182 * called when the document start being processed.
1183 */
1184static void
1185startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
1186{
1187 callbacks++;
1188 if (noout)
1189 return;
1190 fprintf(stdout, "SAX.startDocument()\n");
1191}
1192
1193/**
1194 * endDocumentDebug:
1195 * @ctxt: An XML parser context
1196 *
1197 * called when the document end has been detected.
1198 */
1199static void
1200endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
1201{
1202 callbacks++;
1203 if (noout)
1204 return;
1205 fprintf(stdout, "SAX.endDocument()\n");
1206}
1207
1208/**
1209 * startElementDebug:
1210 * @ctxt: An XML parser context
1211 * @name: The element name
1212 *
1213 * called when an opening tag has been processed.
1214 */
1215static void
1216startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
1217{
1218 int i;
1219
1220 callbacks++;
1221 if (noout)
1222 return;
1223 fprintf(stdout, "SAX.startElement(%s", (char *) name);
1224 if (atts != NULL) {
1225 for (i = 0;(atts[i] != NULL);i++) {
1226 fprintf(stdout, ", %s='", atts[i++]);
1227 if (atts[i] != NULL)
1228 fprintf(stdout, "%s'", atts[i]);
1229 }
1230 }
1231 fprintf(stdout, ")\n");
1232}
1233
1234/**
1235 * endElementDebug:
1236 * @ctxt: An XML parser context
1237 * @name: The element name
1238 *
1239 * called when the end of an element has been detected.
1240 */
1241static void
1242endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1243{
1244 callbacks++;
1245 if (noout)
1246 return;
1247 fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
1248}
1249
1250/**
1251 * charactersDebug:
1252 * @ctxt: An XML parser context
1253 * @ch: a xmlChar string
1254 * @len: the number of xmlChar
1255 *
1256 * receiving some chars from the parser.
1257 * Question: how much at a time ???
1258 */
1259static void
1260charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
1261{
1262 char out[40];
1263 int i;
1264
1265 callbacks++;
1266 if (noout)
1267 return;
1268 for (i = 0;(i<len) && (i < 30);i++)
1269 out[i] = ch[i];
1270 out[i] = 0;
1271
1272 fprintf(stdout, "SAX.characters(%s, %d)\n", out, len);
1273}
1274
1275/**
1276 * referenceDebug:
1277 * @ctxt: An XML parser context
1278 * @name: The entity name
1279 *
1280 * called when an entity reference is detected.
1281 */
1282static void
1283referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1284{
1285 callbacks++;
1286 if (noout)
1287 return;
1288 fprintf(stdout, "SAX.reference(%s)\n", name);
1289}
1290
1291/**
1292 * ignorableWhitespaceDebug:
1293 * @ctxt: An XML parser context
1294 * @ch: a xmlChar string
1295 * @start: the first char in the string
1296 * @len: the number of xmlChar
1297 *
1298 * receiving some ignorable whitespaces from the parser.
1299 * Question: how much at a time ???
1300 */
1301static void
1302ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
1303{
1304 char out[40];
1305 int i;
1306
1307 callbacks++;
1308 if (noout)
1309 return;
1310 for (i = 0;(i<len) && (i < 30);i++)
1311 out[i] = ch[i];
1312 out[i] = 0;
1313 fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", out, len);
1314}
1315
1316/**
1317 * processingInstructionDebug:
1318 * @ctxt: An XML parser context
1319 * @target: the target name
1320 * @data: the PI data's
1321 * @len: the number of xmlChar
1322 *
1323 * A processing instruction has been parsed.
1324 */
1325static void
1326processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
1327 const xmlChar *data)
1328{
1329 callbacks++;
1330 if (noout)
1331 return;
1332 if (data != NULL)
1333 fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
1334 (char *) target, (char *) data);
1335 else
1336 fprintf(stdout, "SAX.processingInstruction(%s, NULL)\n",
1337 (char *) target);
1338}
1339
1340/**
1341 * cdataBlockDebug:
1342 * @ctx: the user data (XML parser context)
1343 * @value: The pcdata content
1344 * @len: the block length
1345 *
1346 * called when a pcdata block has been parsed
1347 */
1348static void
1349cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
1350{
1351 callbacks++;
1352 if (noout)
1353 return;
1354 fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
1355 (char *) value, len);
1356}
1357
1358/**
1359 * commentDebug:
1360 * @ctxt: An XML parser context
1361 * @value: the comment content
1362 *
1363 * A comment has been parsed.
1364 */
1365static void
1366commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
1367{
1368 callbacks++;
1369 if (noout)
1370 return;
1371 fprintf(stdout, "SAX.comment(%s)\n", value);
1372}
1373
1374/**
1375 * warningDebug:
1376 * @ctxt: An XML parser context
1377 * @msg: the message to display/transmit
1378 * @...: extra parameters for the message display
1379 *
1380 * Display and format a warning messages, gives file, line, position and
1381 * extra parameters.
1382 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001383static void XMLCDECL
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001384warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1385{
1386 va_list args;
1387
1388 callbacks++;
1389 if (noout)
1390 return;
1391 va_start(args, msg);
1392 fprintf(stdout, "SAX.warning: ");
1393 vfprintf(stdout, msg, args);
1394 va_end(args);
1395}
1396
1397/**
1398 * errorDebug:
1399 * @ctxt: An XML parser context
1400 * @msg: the message to display/transmit
1401 * @...: extra parameters for the message display
1402 *
1403 * Display and format a error messages, gives file, line, position and
1404 * extra parameters.
1405 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001406static void XMLCDECL
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001407errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1408{
1409 va_list args;
1410
1411 callbacks++;
1412 if (noout)
1413 return;
1414 va_start(args, msg);
1415 fprintf(stdout, "SAX.error: ");
1416 vfprintf(stdout, msg, args);
1417 va_end(args);
1418}
1419
1420/**
1421 * fatalErrorDebug:
1422 * @ctxt: An XML parser context
1423 * @msg: the message to display/transmit
1424 * @...: extra parameters for the message display
1425 *
1426 * Display and format a fatalError messages, gives file, line, position and
1427 * extra parameters.
1428 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001429static void XMLCDECL
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001430fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1431{
1432 va_list args;
1433
1434 callbacks++;
1435 if (noout)
1436 return;
1437 va_start(args, msg);
1438 fprintf(stdout, "SAX.fatalError: ");
1439 vfprintf(stdout, msg, args);
1440 va_end(args);
1441}
1442
Daniel Veillard24505b02005-07-28 23:49:35 +00001443static xmlSAXHandler debugSAXHandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001444 internalSubsetDebug,
1445 isStandaloneDebug,
1446 hasInternalSubsetDebug,
1447 hasExternalSubsetDebug,
1448 resolveEntityDebug,
1449 getEntityDebug,
1450 entityDeclDebug,
1451 notationDeclDebug,
1452 attributeDeclDebug,
1453 elementDeclDebug,
1454 unparsedEntityDeclDebug,
1455 setDocumentLocatorDebug,
1456 startDocumentDebug,
1457 endDocumentDebug,
1458 startElementDebug,
1459 endElementDebug,
1460 referenceDebug,
1461 charactersDebug,
1462 ignorableWhitespaceDebug,
1463 processingInstructionDebug,
1464 commentDebug,
1465 warningDebug,
1466 errorDebug,
1467 fatalErrorDebug,
1468 getParameterEntityDebug,
1469 cdataBlockDebug,
1470 externalSubsetDebug,
1471 1,
1472 NULL,
1473 NULL,
1474 NULL,
1475 NULL
1476};
1477
1478xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
1479
1480/*
1481 * SAX2 specific callbacks
1482 */
1483/**
1484 * startElementNsDebug:
1485 * @ctxt: An XML parser context
1486 * @name: The element name
1487 *
1488 * called when an opening tag has been processed.
1489 */
1490static void
1491startElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
1492 const xmlChar *localname,
1493 const xmlChar *prefix,
1494 const xmlChar *URI,
1495 int nb_namespaces,
1496 const xmlChar **namespaces,
1497 int nb_attributes,
1498 int nb_defaulted,
1499 const xmlChar **attributes)
1500{
1501 int i;
1502
1503 callbacks++;
1504 if (noout)
1505 return;
1506 fprintf(stdout, "SAX.startElementNs(%s", (char *) localname);
1507 if (prefix == NULL)
1508 fprintf(stdout, ", NULL");
1509 else
1510 fprintf(stdout, ", %s", (char *) prefix);
1511 if (URI == NULL)
1512 fprintf(stdout, ", NULL");
1513 else
1514 fprintf(stdout, ", '%s'", (char *) URI);
1515 fprintf(stdout, ", %d", nb_namespaces);
1516
1517 if (namespaces != NULL) {
1518 for (i = 0;i < nb_namespaces * 2;i++) {
1519 fprintf(stdout, ", xmlns");
1520 if (namespaces[i] != NULL)
1521 fprintf(stdout, ":%s", namespaces[i]);
1522 i++;
1523 fprintf(stdout, "='%s'", namespaces[i]);
1524 }
1525 }
1526 fprintf(stdout, ", %d, %d", nb_attributes, nb_defaulted);
1527 if (attributes != NULL) {
1528 for (i = 0;i < nb_attributes * 5;i += 5) {
1529 if (attributes[i + 1] != NULL)
1530 fprintf(stdout, ", %s:%s='", attributes[i + 1], attributes[i]);
1531 else
1532 fprintf(stdout, ", %s='", attributes[i]);
1533 fprintf(stdout, "%.4s...', %d", attributes[i + 3],
1534 (int)(attributes[i + 4] - attributes[i + 3]));
1535 }
1536 }
1537 fprintf(stdout, ")\n");
1538}
1539
1540/**
1541 * endElementDebug:
1542 * @ctxt: An XML parser context
1543 * @name: The element name
1544 *
1545 * called when the end of an element has been detected.
1546 */
1547static void
1548endElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
1549 const xmlChar *localname,
1550 const xmlChar *prefix,
1551 const xmlChar *URI)
1552{
1553 callbacks++;
1554 if (noout)
1555 return;
1556 fprintf(stdout, "SAX.endElementNs(%s", (char *) localname);
1557 if (prefix == NULL)
1558 fprintf(stdout, ", NULL");
1559 else
1560 fprintf(stdout, ", %s", (char *) prefix);
1561 if (URI == NULL)
1562 fprintf(stdout, ", NULL)\n");
1563 else
1564 fprintf(stdout, ", '%s')\n", (char *) URI);
1565}
1566
Daniel Veillard24505b02005-07-28 23:49:35 +00001567static xmlSAXHandler debugSAX2HandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001568 internalSubsetDebug,
1569 isStandaloneDebug,
1570 hasInternalSubsetDebug,
1571 hasExternalSubsetDebug,
1572 resolveEntityDebug,
1573 getEntityDebug,
1574 entityDeclDebug,
1575 notationDeclDebug,
1576 attributeDeclDebug,
1577 elementDeclDebug,
1578 unparsedEntityDeclDebug,
1579 setDocumentLocatorDebug,
1580 startDocumentDebug,
1581 endDocumentDebug,
1582 NULL,
1583 NULL,
1584 referenceDebug,
1585 charactersDebug,
1586 ignorableWhitespaceDebug,
1587 processingInstructionDebug,
1588 commentDebug,
1589 warningDebug,
1590 errorDebug,
1591 fatalErrorDebug,
1592 getParameterEntityDebug,
1593 cdataBlockDebug,
1594 externalSubsetDebug,
1595 XML_SAX2_MAGIC,
1596 NULL,
1597 startElementNsDebug,
1598 endElementNsDebug,
1599 NULL
1600};
1601
Daniel Veillard24505b02005-07-28 23:49:35 +00001602static xmlSAXHandlerPtr debugSAX2Handler = &debugSAX2HandlerStruct;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001603
1604static void
1605testSAX(const char *filename) {
1606 xmlSAXHandlerPtr handler;
1607 const char *user_data = "user_data"; /* mostly for debugging */
1608 xmlParserInputBufferPtr buf = NULL;
1609 xmlParserInputPtr inputStream;
1610 xmlParserCtxtPtr ctxt = NULL;
1611 xmlSAXHandlerPtr old_sax = NULL;
1612
1613 callbacks = 0;
1614
1615 if (noout) {
1616 handler = emptySAXHandler;
Daniel Veillard78dfc9f2005-07-10 22:30:30 +00001617#ifdef LIBXML_SAX1_ENABLED
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001618 } else if (sax1) {
1619 handler = debugSAXHandler;
Daniel Veillard78dfc9f2005-07-10 22:30:30 +00001620#endif
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001621 } else {
1622 handler = debugSAX2Handler;
1623 }
1624
1625 /*
1626 * it's not the simplest code but the most generic in term of I/O
1627 */
1628 buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
1629 if (buf == NULL) {
1630 goto error;
1631 }
1632
1633#ifdef LIBXML_SCHEMAS_ENABLED
1634 if (wxschemas != NULL) {
1635 int ret;
1636 xmlSchemaValidCtxtPtr vctxt;
1637
1638 vctxt = xmlSchemaNewValidCtxt(wxschemas);
1639 xmlSchemaSetValidErrors(vctxt,
1640 (xmlSchemaValidityErrorFunc) fprintf,
1641 (xmlSchemaValidityWarningFunc) fprintf,
1642 stderr);
1643
Daniel Veillard971771e2005-07-09 17:32:57 +00001644 ret = xmlSchemaValidateStream(vctxt, buf, 0, handler,
1645 (void *)user_data);
1646 if (repeat == 0) {
1647 if (ret == 0) {
1648 fprintf(stderr, "%s validates\n", filename);
1649 } else if (ret > 0) {
1650 fprintf(stderr, "%s fails to validate\n", filename);
1651 progresult = XMLLINT_ERR_VALID;
1652 } else {
1653 fprintf(stderr, "%s validation generated an internal error\n",
1654 filename);
1655 progresult = XMLLINT_ERR_VALID;
1656 }
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001657 }
1658 xmlSchemaFreeValidCtxt(vctxt);
1659 } else
1660#endif
1661 {
1662 /*
1663 * Create the parser context amd hook the input
1664 */
1665 ctxt = xmlNewParserCtxt();
1666 if (ctxt == NULL) {
1667 xmlFreeParserInputBuffer(buf);
1668 goto error;
1669 }
1670 old_sax = ctxt->sax;
1671 ctxt->sax = handler;
1672 ctxt->userData = (void *) user_data;
1673 inputStream = xmlNewIOInputStream(ctxt, buf, XML_CHAR_ENCODING_NONE);
1674 if (inputStream == NULL) {
1675 xmlFreeParserInputBuffer(buf);
1676 goto error;
1677 }
1678 inputPush(ctxt, inputStream);
1679
1680 /* do the parsing */
1681 xmlParseDocument(ctxt);
1682
1683 if (ctxt->myDoc != NULL) {
1684 fprintf(stderr, "SAX generated a doc !\n");
1685 xmlFreeDoc(ctxt->myDoc);
1686 ctxt->myDoc = NULL;
1687 }
1688 }
1689
1690error:
1691 if (ctxt != NULL) {
1692 ctxt->sax = old_sax;
1693 xmlFreeParserCtxt(ctxt);
1694 }
1695}
1696
Daniel Veillard5e873c42000-04-12 13:27:38 +00001697/************************************************************************
1698 * *
Daniel Veillard7704fb12003-01-03 16:19:51 +00001699 * Stream Test processing *
1700 * *
1701 ************************************************************************/
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001702#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00001703static void processNode(xmlTextReaderPtr reader) {
Daniel Veillard198c1bf2003-10-20 17:07:41 +00001704 const xmlChar *name, *value;
Daniel Veillard16ef8002005-01-31 00:27:50 +00001705 int type, empty;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001706
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001707 type = xmlTextReaderNodeType(reader);
Daniel Veillard16ef8002005-01-31 00:27:50 +00001708 empty = xmlTextReaderIsEmptyElement(reader);
Daniel Veillard99737f52003-03-22 14:55:50 +00001709
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001710 if (debug) {
1711 name = xmlTextReaderConstName(reader);
1712 if (name == NULL)
1713 name = BAD_CAST "--";
Daniel Veillard7704fb12003-01-03 16:19:51 +00001714
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001715 value = xmlTextReaderConstValue(reader);
1716
1717
1718 printf("%d %d %s %d %d",
1719 xmlTextReaderDepth(reader),
1720 type,
1721 name,
Daniel Veillard16ef8002005-01-31 00:27:50 +00001722 empty,
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001723 xmlTextReaderHasValue(reader));
1724 if (value == NULL)
1725 printf("\n");
1726 else {
1727 printf(" %s\n", value);
1728 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001729 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001730#ifdef LIBXML_PATTERN_ENABLED
1731 if (patternc) {
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001732 xmlChar *path = NULL;
1733 int match = -1;
1734
1735 if (type == XML_READER_TYPE_ELEMENT) {
1736 /* do the check only on element start */
1737 match = xmlPatternMatch(patternc, xmlTextReaderCurrentNode(reader));
1738
1739 if (match) {
1740 path = xmlGetNodePath(xmlTextReaderCurrentNode(reader));
1741 printf("Node %s matches pattern %s\n", path, pattern);
1742 }
1743 }
1744 if (patstream != NULL) {
1745 int ret;
1746
1747 if (type == XML_READER_TYPE_ELEMENT) {
1748 ret = xmlStreamPush(patstream,
1749 xmlTextReaderConstLocalName(reader),
1750 xmlTextReaderConstNamespaceUri(reader));
1751 if (ret < 0) {
1752 fprintf(stderr, "xmlStreamPush() failure\n");
1753 xmlFreeStreamCtxt(patstream);
1754 patstream = NULL;
1755 } else if (ret != match) {
1756 if (path == NULL) {
1757 path = xmlGetNodePath(
1758 xmlTextReaderCurrentNode(reader));
1759 }
1760 fprintf(stderr,
1761 "xmlPatternMatch and xmlStreamPush disagree\n");
1762 fprintf(stderr,
1763 " pattern %s node %s\n",
1764 pattern, path);
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001765 }
1766
1767
Daniel Veillard16ef8002005-01-31 00:27:50 +00001768 }
1769 if ((type == XML_READER_TYPE_END_ELEMENT) ||
1770 ((type == XML_READER_TYPE_ELEMENT) && (empty))) {
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001771 ret = xmlStreamPop(patstream);
1772 if (ret < 0) {
1773 fprintf(stderr, "xmlStreamPop() failure\n");
1774 xmlFreeStreamCtxt(patstream);
1775 patstream = NULL;
1776 }
1777 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001778 }
Daniel Veillardf9d16912005-01-30 22:36:30 +00001779 if (path != NULL)
1780 xmlFree(path);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001781 }
1782#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001783}
1784
1785static void streamFile(char *filename) {
1786 xmlTextReaderPtr reader;
1787 int ret;
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001788#ifdef HAVE_SYS_MMAN_H
1789 int fd = -1;
1790 struct stat info;
1791 const char *base = NULL;
1792 xmlParserInputBufferPtr input = NULL;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001793
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001794 if (memory) {
1795 if (stat(filename, &info) < 0)
1796 return;
1797 if ((fd = open(filename, O_RDONLY)) < 0)
1798 return;
1799 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
1800 if (base == (void *) MAP_FAILED)
1801 return;
1802
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001803 reader = xmlReaderForMemory(base, info.st_size, filename,
1804 NULL, options);
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001805 } else
1806#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001807 reader = xmlReaderForFile(filename, NULL, options);
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001808#ifdef LIBXML_PATTERN_ENABLED
Daniel Veillardd4301ab2005-02-03 22:24:10 +00001809 if (pattern != NULL) {
1810 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
1811 if (patternc == NULL) {
1812 xmlGenericError(xmlGenericErrorContext,
1813 "Pattern %s failed to compile\n", pattern);
1814 progresult = XMLLINT_ERR_SCHEMAPAT;
1815 pattern = NULL;
1816 }
1817 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001818 if (patternc != NULL) {
1819 patstream = xmlPatternGetStreamCtxt(patternc);
1820 if (patstream != NULL) {
1821 ret = xmlStreamPush(patstream, NULL, NULL);
1822 if (ret < 0) {
1823 fprintf(stderr, "xmlStreamPush() failure\n");
1824 xmlFreeStreamCtxt(patstream);
1825 patstream = NULL;
1826 }
1827 }
1828 }
1829#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001830
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001831
Daniel Veillard7704fb12003-01-03 16:19:51 +00001832 if (reader != NULL) {
Daniel Veillard4432df22003-09-28 18:58:27 +00001833#ifdef LIBXML_VALID_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00001834 if (valid)
1835 xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
Daniel Veillardce192eb2003-04-16 15:58:05 +00001836 else
Daniel Veillard4432df22003-09-28 18:58:27 +00001837#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardce192eb2003-04-16 15:58:05 +00001838 xmlTextReaderSetParserProp(reader, XML_PARSER_LOADDTD, 1);
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001839#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +00001840 if (relaxng != NULL) {
Daniel Veillard81514ba2003-09-16 23:17:26 +00001841 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001842 startTimer();
1843 }
1844 ret = xmlTextReaderRelaxNGValidate(reader, relaxng);
1845 if (ret < 0) {
1846 xmlGenericError(xmlGenericErrorContext,
1847 "Relax-NG schema %s failed to compile\n", relaxng);
William M. Brack8304d872004-06-08 13:29:32 +00001848 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillardce192eb2003-04-16 15:58:05 +00001849 relaxng = NULL;
1850 }
Daniel Veillard81514ba2003-09-16 23:17:26 +00001851 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001852 endTimer("Compiling the schemas");
1853 }
1854 }
Daniel Veillardf10ae122005-07-10 19:03:16 +00001855 if (schema != NULL) {
1856 if ((timing) && (!repeat)) {
1857 startTimer();
1858 }
1859 ret = xmlTextReaderSchemaValidate(reader, schema);
1860 if (ret < 0) {
1861 xmlGenericError(xmlGenericErrorContext,
1862 "XSD schema %s failed to compile\n", schema);
1863 progresult = XMLLINT_ERR_SCHEMACOMP;
1864 schema = NULL;
1865 }
1866 if ((timing) && (!repeat)) {
1867 endTimer("Compiling the schemas");
1868 }
1869 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001870#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001871
1872 /*
1873 * Process all nodes in sequence
1874 */
Daniel Veillard81514ba2003-09-16 23:17:26 +00001875 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001876 startTimer();
1877 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001878 ret = xmlTextReaderRead(reader);
1879 while (ret == 1) {
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001880 if ((debug)
1881#ifdef LIBXML_PATTERN_ENABLED
1882 || (patternc)
1883#endif
1884 )
Daniel Veillard7704fb12003-01-03 16:19:51 +00001885 processNode(reader);
1886 ret = xmlTextReaderRead(reader);
1887 }
Daniel Veillard81514ba2003-09-16 23:17:26 +00001888 if ((timing) && (!repeat)) {
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001889#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf54cd532004-02-25 11:52:31 +00001890 if (relaxng != NULL)
Daniel Veillard49138f12004-02-19 12:58:36 +00001891 endTimer("Parsing and validating");
1892 else
Daniel Veillardf54cd532004-02-25 11:52:31 +00001893#endif
Daniel Veillard4432df22003-09-28 18:58:27 +00001894#ifdef LIBXML_VALID_ENABLED
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001895 if (valid)
Daniel Veillardce192eb2003-04-16 15:58:05 +00001896 endTimer("Parsing and validating");
1897 else
Daniel Veillard4432df22003-09-28 18:58:27 +00001898#endif
Daniel Veillardf54cd532004-02-25 11:52:31 +00001899 endTimer("Parsing");
Daniel Veillardce192eb2003-04-16 15:58:05 +00001900 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001901
Daniel Veillard4432df22003-09-28 18:58:27 +00001902#ifdef LIBXML_VALID_ENABLED
Daniel Veillardf6bad792003-04-11 19:38:54 +00001903 if (valid) {
1904 if (xmlTextReaderIsValid(reader) != 1) {
1905 xmlGenericError(xmlGenericErrorContext,
1906 "Document %s does not validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001907 progresult = XMLLINT_ERR_VALID;
Daniel Veillardf6bad792003-04-11 19:38:54 +00001908 }
1909 }
Daniel Veillard4432df22003-09-28 18:58:27 +00001910#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001911#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf10ae122005-07-10 19:03:16 +00001912 if ((relaxng != NULL) || (schema != NULL)) {
Daniel Veillardf4e55762003-04-15 23:32:22 +00001913 if (xmlTextReaderIsValid(reader) != 1) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001914 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001915 progresult = XMLLINT_ERR_VALID;
Daniel Veillardf4e55762003-04-15 23:32:22 +00001916 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001917 fprintf(stderr, "%s validates\n", filename);
Daniel Veillardf4e55762003-04-15 23:32:22 +00001918 }
1919 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001920#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001921 /*
1922 * Done, cleanup and status
1923 */
1924 xmlFreeTextReader(reader);
1925 if (ret != 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001926 fprintf(stderr, "%s : failed to parse\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001927 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001928 }
1929 } else {
1930 fprintf(stderr, "Unable to open %s\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001931 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001932 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001933#ifdef LIBXML_PATTERN_ENABLED
1934 if (patstream != NULL) {
1935 xmlFreeStreamCtxt(patstream);
1936 patstream = NULL;
1937 }
1938#endif
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001939#ifdef HAVE_SYS_MMAN_H
1940 if (memory) {
1941 xmlFreeParserInputBuffer(input);
1942 munmap((char *) base, info.st_size);
1943 close(fd);
1944 }
1945#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001946}
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001947
1948static void walkDoc(xmlDocPtr doc) {
1949 xmlTextReaderPtr reader;
1950 int ret;
1951
Daniel Veillardd4301ab2005-02-03 22:24:10 +00001952#ifdef LIBXML_PATTERN_ENABLED
1953 xmlNodePtr root;
1954 const xmlChar *namespaces[22];
1955 int i;
1956 xmlNsPtr ns;
1957
1958 root = xmlDocGetRootElement(doc);
1959 for (ns = root->nsDef, i = 0;ns != NULL && i < 20;ns=ns->next) {
1960 namespaces[i++] = ns->href;
1961 namespaces[i++] = ns->prefix;
1962 }
1963 namespaces[i++] = NULL;
1964 namespaces[i++] = NULL;
1965
1966 if (pattern != NULL) {
1967 patternc = xmlPatterncompile((const xmlChar *) pattern, doc->dict,
1968 0, &namespaces[0]);
1969 if (patternc == NULL) {
1970 xmlGenericError(xmlGenericErrorContext,
1971 "Pattern %s failed to compile\n", pattern);
1972 progresult = XMLLINT_ERR_SCHEMAPAT;
1973 pattern = NULL;
1974 }
1975 }
Daniel Veillard2b2e02d2005-02-05 23:20:22 +00001976 if (patternc != NULL) {
1977 patstream = xmlPatternGetStreamCtxt(patternc);
1978 if (patstream != NULL) {
1979 ret = xmlStreamPush(patstream, NULL, NULL);
1980 if (ret < 0) {
1981 fprintf(stderr, "xmlStreamPush() failure\n");
1982 xmlFreeStreamCtxt(patstream);
1983 patstream = NULL;
1984 }
1985 }
1986 }
Daniel Veillardd4301ab2005-02-03 22:24:10 +00001987#endif /* LIBXML_PATTERN_ENABLED */
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001988 reader = xmlReaderWalker(doc);
1989 if (reader != NULL) {
1990 if ((timing) && (!repeat)) {
1991 startTimer();
1992 }
1993 ret = xmlTextReaderRead(reader);
1994 while (ret == 1) {
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001995 if ((debug)
1996#ifdef LIBXML_PATTERN_ENABLED
1997 || (patternc)
1998#endif
1999 )
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002000 processNode(reader);
2001 ret = xmlTextReaderRead(reader);
2002 }
2003 if ((timing) && (!repeat)) {
2004 endTimer("walking through the doc");
2005 }
2006 xmlFreeTextReader(reader);
2007 if (ret != 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002008 fprintf(stderr, "failed to walk through the doc\n");
William M. Brack8304d872004-06-08 13:29:32 +00002009 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002010 }
2011 } else {
2012 fprintf(stderr, "Failed to crate a reader from the document\n");
William M. Brack8304d872004-06-08 13:29:32 +00002013 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002014 }
Daniel Veillard2b2e02d2005-02-05 23:20:22 +00002015#ifdef LIBXML_PATTERN_ENABLED
2016 if (patstream != NULL) {
2017 xmlFreeStreamCtxt(patstream);
2018 patstream = NULL;
2019 }
2020#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002021}
Daniel Veillard81273902003-09-30 00:43:48 +00002022#endif /* LIBXML_READER_ENABLED */
Daniel Veillard7704fb12003-01-03 16:19:51 +00002023
2024/************************************************************************
2025 * *
2026 * Tree Test processing *
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002027 * *
2028 ************************************************************************/
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002029static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
Daniel Veillard652327a2003-09-29 18:02:38 +00002030 xmlDocPtr doc = NULL;
2031#ifdef LIBXML_TREE_ENABLED
2032 xmlDocPtr tmp;
2033#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002034
Daniel Veillard48b2f892001-02-25 16:11:03 +00002035 if ((timing) && (!repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00002036 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002037
2038
Daniel Veillard652327a2003-09-29 18:02:38 +00002039#ifdef LIBXML_TREE_ENABLED
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002040 if (filename == NULL) {
2041 if (generate) {
2042 xmlNodePtr n;
2043
2044 doc = xmlNewDoc(BAD_CAST "1.0");
Daniel Veillard95ddcd32004-10-26 21:53:55 +00002045 n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002046 xmlNodeSetContent(n, BAD_CAST "abc");
2047 xmlDocSetRootElement(doc, n);
2048 }
2049 }
Daniel Veillard652327a2003-09-29 18:02:38 +00002050#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002051#ifdef LIBXML_HTML_ENABLED
Daniel Veillard73b013f2003-09-30 12:36:01 +00002052#ifdef LIBXML_PUSH_ENABLED
William M. Brack78637da2003-07-31 14:47:38 +00002053 else if ((html) && (push)) {
2054 FILE *f;
2055
William M. Brack3403add2004-06-27 02:07:51 +00002056#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2057 f = fopen(filename, "rb");
2058#else
2059 f = fopen(filename, "r");
2060#endif
William M. Brack78637da2003-07-31 14:47:38 +00002061 if (f != NULL) {
2062 int res, size = 3;
2063 char chars[4096];
2064 htmlParserCtxtPtr ctxt;
2065
2066 /* if (repeat) */
2067 size = 4096;
2068 res = fread(chars, 1, 4, f);
2069 if (res > 0) {
2070 ctxt = htmlCreatePushParserCtxt(NULL, NULL,
William M. Brack1d75c8a2003-10-27 13:48:16 +00002071 chars, res, filename, XML_CHAR_ENCODING_NONE);
William M. Brack78637da2003-07-31 14:47:38 +00002072 while ((res = fread(chars, 1, size, f)) > 0) {
2073 htmlParseChunk(ctxt, chars, res, 0);
2074 }
2075 htmlParseChunk(ctxt, chars, 0, 1);
2076 doc = ctxt->myDoc;
2077 htmlFreeParserCtxt(ctxt);
2078 }
2079 fclose(f);
2080 }
2081 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00002082#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002083 else if (html) {
Daniel Veillard9475a352003-09-26 12:47:50 +00002084 doc = htmlReadFile(filename, NULL, options);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002085 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002086#endif /* LIBXML_HTML_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002087 else {
Daniel Veillard73b013f2003-09-30 12:36:01 +00002088#ifdef LIBXML_PUSH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002089 /*
2090 * build an XML tree from a string;
2091 */
2092 if (push) {
2093 FILE *f;
2094
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002095 /* '-' Usually means stdin -<sven@zen.org> */
2096 if ((filename[0] == '-') && (filename[1] == 0)) {
2097 f = stdin;
2098 } else {
William M. Brack3403add2004-06-27 02:07:51 +00002099#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2100 f = fopen(filename, "rb");
2101#else
2102 f = fopen(filename, "r");
2103#endif
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002104 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002105 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +00002106 int ret;
Daniel Veillarda880b122003-04-21 21:36:41 +00002107 int res, size = 1024;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002108 char chars[1024];
2109 xmlParserCtxtPtr ctxt;
2110
Daniel Veillarda880b122003-04-21 21:36:41 +00002111 /* if (repeat) size = 1024; */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002112 res = fread(chars, 1, 4, f);
2113 if (res > 0) {
2114 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
2115 chars, res, filename);
Daniel Veillard500a1de2004-03-22 15:22:58 +00002116 xmlCtxtUseOptions(ctxt, options);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002117 while ((res = fread(chars, 1, size, f)) > 0) {
2118 xmlParseChunk(ctxt, chars, res, 0);
2119 }
2120 xmlParseChunk(ctxt, chars, 0, 1);
2121 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +00002122 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002123 xmlFreeParserCtxt(ctxt);
Daniel Veillarde715dd22000-08-29 18:29:38 +00002124 if (!ret) {
2125 xmlFreeDoc(doc);
2126 doc = NULL;
2127 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002128 }
2129 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00002130 } else
2131#endif /* LIBXML_PUSH_ENABLED */
2132 if (testIO) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002133 if ((filename[0] == '-') && (filename[1] == 0)) {
Daniel Veillard60942de2003-09-25 21:05:58 +00002134 doc = xmlReadFd(0, NULL, NULL, options);
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002135 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002136 FILE *f;
Daniel Veillard5e873c42000-04-12 13:27:38 +00002137
William M. Brack3403add2004-06-27 02:07:51 +00002138#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2139 f = fopen(filename, "rb");
2140#else
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002141 f = fopen(filename, "r");
William M. Brack3403add2004-06-27 02:07:51 +00002142#endif
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002143 if (f != NULL) {
2144 if (rectxt == NULL)
2145 doc = xmlReadIO((xmlInputReadCallback) myRead,
2146 (xmlInputCloseCallback) myClose, f,
Daniel Veillard60942de2003-09-25 21:05:58 +00002147 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002148 else
2149 doc = xmlCtxtReadIO(rectxt,
2150 (xmlInputReadCallback) myRead,
2151 (xmlInputCloseCallback) myClose, f,
Daniel Veillard60942de2003-09-25 21:05:58 +00002152 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002153 } else
Daniel Veillard5e873c42000-04-12 13:27:38 +00002154 doc = NULL;
Daniel Veillard5e873c42000-04-12 13:27:38 +00002155 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002156 } else if (htmlout) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002157 xmlParserCtxtPtr ctxt;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002158
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002159 if (rectxt == NULL)
2160 ctxt = xmlNewParserCtxt();
2161 else
2162 ctxt = rectxt;
Daniel Veillard88a172f2000-08-04 18:23:10 +00002163 if (ctxt == NULL) {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002164 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +00002165 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002166 ctxt->sax->error = xmlHTMLError;
2167 ctxt->sax->warning = xmlHTMLWarning;
2168 ctxt->vctxt.error = xmlHTMLValidityError;
2169 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002170
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002171 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002172
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002173 if (rectxt == NULL)
2174 xmlFreeParserCtxt(ctxt);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002175 }
Daniel Veillard46e370e2000-07-21 20:32:03 +00002176#ifdef HAVE_SYS_MMAN_H
2177 } else if (memory) {
2178 int fd;
2179 struct stat info;
2180 const char *base;
2181 if (stat(filename, &info) < 0)
2182 return;
2183 if ((fd = open(filename, O_RDONLY)) < 0)
2184 return;
2185 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillard29579362000-08-14 17:57:48 +00002186 if (base == (void *) MAP_FAILED)
Daniel Veillard46e370e2000-07-21 20:32:03 +00002187 return;
2188
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002189 if (rectxt == NULL)
Daniel Veillard60942de2003-09-25 21:05:58 +00002190 doc = xmlReadMemory((char *) base, info.st_size,
2191 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002192 else
Daniel Veillard60942de2003-09-25 21:05:58 +00002193 doc = xmlCtxtReadMemory(rectxt, (char *) base, info.st_size,
2194 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002195
Daniel Veillard46e370e2000-07-21 20:32:03 +00002196 munmap((char *) base, info.st_size);
2197#endif
Daniel Veillard4432df22003-09-28 18:58:27 +00002198#ifdef LIBXML_VALID_ENABLED
Daniel Veillardea7751d2002-12-20 00:16:24 +00002199 } else if (valid) {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002200 xmlParserCtxtPtr ctxt = NULL;
Daniel Veillardea7751d2002-12-20 00:16:24 +00002201
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002202 if (rectxt == NULL)
2203 ctxt = xmlNewParserCtxt();
2204 else
2205 ctxt = rectxt;
Daniel Veillardea7751d2002-12-20 00:16:24 +00002206 if (ctxt == NULL) {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002207 doc = NULL;
Daniel Veillardea7751d2002-12-20 00:16:24 +00002208 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002209 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
2210
2211 if (ctxt->valid == 0)
William M. Brack8304d872004-06-08 13:29:32 +00002212 progresult = XMLLINT_ERR_RDFILE;
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002213 if (rectxt == NULL)
2214 xmlFreeParserCtxt(ctxt);
Daniel Veillardea7751d2002-12-20 00:16:24 +00002215 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002216#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardea7751d2002-12-20 00:16:24 +00002217 } else {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002218 if (rectxt != NULL)
2219 doc = xmlCtxtReadFile(rectxt, filename, NULL, options);
Daniel Veillard81562d22005-06-15 13:27:56 +00002220 else {
2221#ifdef LIBXML_SAX1_ENABLED
2222 if (sax1)
2223 doc = xmlParseFile(filename);
2224 else
2225#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002226 doc = xmlReadFile(filename, NULL, options);
Daniel Veillard81562d22005-06-15 13:27:56 +00002227 }
Daniel Veillardea7751d2002-12-20 00:16:24 +00002228 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002229 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002230
Daniel Veillard88a172f2000-08-04 18:23:10 +00002231 /*
2232 * If we don't have a document we might as well give up. Do we
2233 * want an error message here? <sven@zen.org> */
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002234 if (doc == NULL) {
William M. Brack8304d872004-06-08 13:29:32 +00002235 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard88a172f2000-08-04 18:23:10 +00002236 return;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002237 }
2238
Daniel Veillard48b2f892001-02-25 16:11:03 +00002239 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002240 endTimer("Parsing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002241 }
2242
Daniel Veillard29e43992001-12-13 22:21:58 +00002243 /*
2244 * Remove DOCTYPE nodes
2245 */
2246 if (dropdtd) {
2247 xmlDtdPtr dtd;
2248
2249 dtd = xmlGetIntSubset(doc);
2250 if (dtd != NULL) {
2251 xmlUnlinkNode((xmlNodePtr)dtd);
2252 xmlFreeDtd(dtd);
2253 }
2254 }
2255
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002256#ifdef LIBXML_XINCLUDE_ENABLED
Daniel Veillard48b2f892001-02-25 16:11:03 +00002257 if (xinclude) {
2258 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002259 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002260 }
William M. Brack4e1c2db2005-02-11 10:58:55 +00002261 if (xmlXIncludeProcessFlags(doc, options) < 0)
2262 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard48b2f892001-02-25 16:11:03 +00002263 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002264 endTimer("Xinclude processing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002265 }
2266 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002267#endif
Daniel Veillard88a172f2000-08-04 18:23:10 +00002268
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002269#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00002270#ifdef LIBXML_XPATH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002271 /*
Daniel Veillardcbaf3992001-12-31 16:16:02 +00002272 * shell interaction
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002273 */
2274 if (shell)
2275 xmlShell(doc, filename, xmlShellReadline, stdout);
2276#endif
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00002277#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002278
Daniel Veillard652327a2003-09-29 18:02:38 +00002279#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002280 /*
2281 * test intermediate copy if needed.
2282 */
2283 if (copy) {
2284 tmp = doc;
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002285 if (timing) {
2286 startTimer();
2287 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002288 doc = xmlCopyDoc(doc, 1);
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002289 if (timing) {
2290 endTimer("Copying");
2291 }
2292 if (timing) {
2293 startTimer();
2294 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002295 xmlFreeDoc(tmp);
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002296 if (timing) {
2297 endTimer("Freeing original");
2298 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002299 }
Daniel Veillard652327a2003-09-29 18:02:38 +00002300#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002301
Daniel Veillard4432df22003-09-28 18:58:27 +00002302#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002303 if ((insert) && (!html)) {
2304 const xmlChar* list[256];
2305 int nb, i;
2306 xmlNodePtr node;
2307
2308 if (doc->children != NULL) {
2309 node = doc->children;
2310 while ((node != NULL) && (node->last == NULL)) node = node->next;
2311 if (node != NULL) {
2312 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
2313 if (nb < 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002314 fprintf(stderr, "could not get valid list of elements\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002315 } else if (nb == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002316 fprintf(stderr, "No element can be inserted under root\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002317 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002318 fprintf(stderr, "%d element types can be inserted under root:\n",
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002319 nb);
2320 for (i = 0;i < nb;i++) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002321 fprintf(stderr, "%s\n", (char *) list[i]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002322 }
2323 }
2324 }
2325 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002326 }else
2327#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002328#ifdef LIBXML_READER_ENABLED
2329 if (walker) {
2330 walkDoc(doc);
2331 }
2332#endif /* LIBXML_READER_ENABLED */
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002333#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard4432df22003-09-28 18:58:27 +00002334 if (noout == 0) {
Daniel Veillard3df01182003-12-10 10:17:51 +00002335 int ret;
2336
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002337 /*
2338 * print it.
2339 */
2340#ifdef LIBXML_DEBUG_ENABLED
2341 if (!debug) {
2342#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00002343 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002344 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002345 }
Daniel Veillard656ce942004-04-30 23:11:45 +00002346#ifdef LIBXML_HTML_ENABLED
Daniel Veillard42fd4122003-11-04 08:47:48 +00002347 if ((html) && (!xmlout)) {
2348 if (compress) {
2349 htmlSaveFile(output ? output : "-", doc);
2350 }
2351 else if (encoding != NULL) {
2352 if ( format ) {
2353 htmlSaveFileFormat(output ? output : "-", doc, encoding, 1);
2354 }
2355 else {
2356 htmlSaveFileFormat(output ? output : "-", doc, encoding, 0);
2357 }
2358 }
2359 else if (format) {
2360 htmlSaveFileFormat(output ? output : "-", doc, NULL, 1);
2361 }
2362 else {
2363 FILE *out;
2364 if (output == NULL)
2365 out = stdout;
2366 else {
2367 out = fopen(output,"wb");
2368 }
2369 if (out != NULL) {
2370 if (htmlDocDump(out, doc) < 0)
William M. Brack8304d872004-06-08 13:29:32 +00002371 progresult = XMLLINT_ERR_OUT;
Daniel Veillard42fd4122003-11-04 08:47:48 +00002372
2373 if (output != NULL)
2374 fclose(out);
2375 } else {
2376 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00002377 progresult = XMLLINT_ERR_OUT;
Daniel Veillard42fd4122003-11-04 08:47:48 +00002378 }
2379 }
2380 if ((timing) && (!repeat)) {
2381 endTimer("Saving");
2382 }
2383 } else
2384#endif
Daniel Veillard25048d82004-08-14 22:37:54 +00002385#ifdef LIBXML_C14N_ENABLED
2386 if (canonical) {
2387 xmlChar *result = NULL;
2388 int size;
2389
2390 size = xmlC14NDocDumpMemory(doc, NULL, 0, NULL, 1, &result);
2391 if (size >= 0) {
2392 write(1, result, size);
2393 xmlFree(result);
2394 } else {
2395 fprintf(stderr, "Failed to canonicalize\n");
2396 progresult = XMLLINT_ERR_OUT;
2397 }
2398 } else
Aleksey Sanin2650df12005-06-06 17:16:50 +00002399 if (exc_canonical) {
2400 xmlChar *result = NULL;
2401 int size;
2402
2403 size = xmlC14NDocDumpMemory(doc, NULL, 1, NULL, 1, &result);
2404 if (size >= 0) {
2405 write(1, result, size);
2406 xmlFree(result);
2407 } else {
2408 fprintf(stderr, "Failed to canonicalize\n");
2409 progresult = XMLLINT_ERR_OUT;
2410 }
2411 } else
Daniel Veillard25048d82004-08-14 22:37:54 +00002412#endif
Daniel Veillard3b2c2612001-04-04 00:09:00 +00002413#ifdef HAVE_SYS_MMAN_H
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002414 if (memory) {
2415 xmlChar *result;
2416 int len;
2417
2418 if (encoding != NULL) {
Daniel Veillardd536f702001-11-08 17:32:47 +00002419 if ( format ) {
2420 xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
2421 } else {
2422 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
2423 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002424 } else {
Daniel Veillard90493a92001-08-14 14:12:47 +00002425 if (format)
2426 xmlDocDumpFormatMemory(doc, &result, &len, 1);
2427 else
2428 xmlDocDumpMemory(doc, &result, &len);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002429 }
2430 if (result == NULL) {
2431 fprintf(stderr, "Failed to save\n");
Daniel Veillard25048d82004-08-14 22:37:54 +00002432 progresult = XMLLINT_ERR_OUT;
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002433 } else {
2434 write(1, result, len);
2435 xmlFree(result);
2436 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +00002437 } else
2438#endif /* HAVE_SYS_MMAN_H */
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002439 if (compress) {
2440 xmlSaveFile(output ? output : "-", doc);
2441 }
Daniel Veillardd536f702001-11-08 17:32:47 +00002442 else if (encoding != NULL) {
2443 if ( format ) {
Daniel Veillard3df01182003-12-10 10:17:51 +00002444 ret = xmlSaveFormatFileEnc(output ? output : "-", doc,
2445 encoding, 1);
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002446 }
Daniel Veillardd536f702001-11-08 17:32:47 +00002447 else {
Daniel Veillard3df01182003-12-10 10:17:51 +00002448 ret = xmlSaveFileEnc(output ? output : "-", doc, encoding);
2449 }
2450 if (ret < 0) {
2451 fprintf(stderr, "failed save to %s\n",
2452 output ? output : "-");
William M. Brack8304d872004-06-08 13:29:32 +00002453 progresult = XMLLINT_ERR_OUT;
Daniel Veillardd536f702001-11-08 17:32:47 +00002454 }
2455 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002456 else if (format) {
Daniel Veillard3df01182003-12-10 10:17:51 +00002457 ret = xmlSaveFormatFile(output ? output : "-", doc, 1);
2458 if (ret < 0) {
2459 fprintf(stderr, "failed save to %s\n",
2460 output ? output : "-");
William M. Brack8304d872004-06-08 13:29:32 +00002461 progresult = XMLLINT_ERR_OUT;
Daniel Veillard3df01182003-12-10 10:17:51 +00002462 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002463 }
2464 else {
2465 FILE *out;
2466 if (output == NULL)
2467 out = stdout;
2468 else {
2469 out = fopen(output,"wb");
2470 }
Daniel Veillard05d987b2003-10-08 11:54:57 +00002471 if (out != NULL) {
Daniel Veillard828ce832003-10-08 19:19:10 +00002472 if (xmlDocDump(out, doc) < 0)
William M. Brack8304d872004-06-08 13:29:32 +00002473 progresult = XMLLINT_ERR_OUT;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002474
Daniel Veillard05d987b2003-10-08 11:54:57 +00002475 if (output != NULL)
2476 fclose(out);
2477 } else {
2478 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00002479 progresult = XMLLINT_ERR_OUT;
Daniel Veillard05d987b2003-10-08 11:54:57 +00002480 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002481 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002482 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002483 endTimer("Saving");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002484 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002485#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002486 } else {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002487 FILE *out;
2488 if (output == NULL)
2489 out = stdout;
2490 else {
2491 out = fopen(output,"wb");
2492 }
Daniel Veillard05d987b2003-10-08 11:54:57 +00002493 if (out != NULL) {
2494 xmlDebugDumpDocument(out, doc);
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002495
Daniel Veillard05d987b2003-10-08 11:54:57 +00002496 if (output != NULL)
2497 fclose(out);
2498 } else {
2499 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00002500 progresult = XMLLINT_ERR_OUT;
Daniel Veillard05d987b2003-10-08 11:54:57 +00002501 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002502 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002503#endif
2504 }
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002505#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002506
Daniel Veillard4432df22003-09-28 18:58:27 +00002507#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002508 /*
2509 * A posteriori validation test
2510 */
Daniel Veillard66f68e72003-08-18 16:39:51 +00002511 if ((dtdvalid != NULL) || (dtdvalidfpi != NULL)) {
Daniel Veillardcd429612000-10-11 15:57:05 +00002512 xmlDtdPtr dtd;
2513
Daniel Veillard48b2f892001-02-25 16:11:03 +00002514 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002515 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002516 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00002517 if (dtdvalid != NULL)
2518 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
2519 else
2520 dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL);
Daniel Veillard48b2f892001-02-25 16:11:03 +00002521 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002522 endTimer("Parsing DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002523 }
Daniel Veillardcd429612000-10-11 15:57:05 +00002524 if (dtd == NULL) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00002525 if (dtdvalid != NULL)
2526 xmlGenericError(xmlGenericErrorContext,
2527 "Could not parse DTD %s\n", dtdvalid);
2528 else
2529 xmlGenericError(xmlGenericErrorContext,
2530 "Could not parse DTD %s\n", dtdvalidfpi);
William M. Brack8304d872004-06-08 13:29:32 +00002531 progresult = XMLLINT_ERR_DTD;
Daniel Veillardcd429612000-10-11 15:57:05 +00002532 } else {
Daniel Veillarda37aab82003-06-09 09:10:36 +00002533 xmlValidCtxtPtr cvp;
2534
2535 if ((cvp = xmlNewValidCtxt()) == NULL) {
2536 xmlGenericError(xmlGenericErrorContext,
2537 "Couldn't allocate validation context\n");
2538 exit(-1);
2539 }
2540 cvp->userData = (void *) stderr;
2541 cvp->error = (xmlValidityErrorFunc) fprintf;
2542 cvp->warning = (xmlValidityWarningFunc) fprintf;
2543
Daniel Veillard48b2f892001-02-25 16:11:03 +00002544 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002545 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002546 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002547 if (!xmlValidateDtd(cvp, doc, dtd)) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00002548 if (dtdvalid != NULL)
2549 xmlGenericError(xmlGenericErrorContext,
2550 "Document %s does not validate against %s\n",
2551 filename, dtdvalid);
2552 else
2553 xmlGenericError(xmlGenericErrorContext,
2554 "Document %s does not validate against %s\n",
2555 filename, dtdvalidfpi);
William M. Brack8304d872004-06-08 13:29:32 +00002556 progresult = XMLLINT_ERR_VALID;
Daniel Veillardcd429612000-10-11 15:57:05 +00002557 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002558 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002559 endTimer("Validating against DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002560 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002561 xmlFreeValidCtxt(cvp);
Daniel Veillardcd429612000-10-11 15:57:05 +00002562 xmlFreeDtd(dtd);
2563 }
2564 } else if (postvalid) {
Daniel Veillarda37aab82003-06-09 09:10:36 +00002565 xmlValidCtxtPtr cvp;
2566
2567 if ((cvp = xmlNewValidCtxt()) == NULL) {
2568 xmlGenericError(xmlGenericErrorContext,
2569 "Couldn't allocate validation context\n");
2570 exit(-1);
2571 }
2572
Daniel Veillard48b2f892001-02-25 16:11:03 +00002573 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002574 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002575 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002576 cvp->userData = (void *) stderr;
2577 cvp->error = (xmlValidityErrorFunc) fprintf;
2578 cvp->warning = (xmlValidityWarningFunc) fprintf;
2579 if (!xmlValidateDocument(cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00002580 xmlGenericError(xmlGenericErrorContext,
2581 "Document %s does not validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002582 progresult = XMLLINT_ERR_VALID;
Daniel Veillardcd429612000-10-11 15:57:05 +00002583 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002584 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002585 endTimer("Validating");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002586 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002587 xmlFreeValidCtxt(cvp);
Daniel Veillard4432df22003-09-28 18:58:27 +00002588 }
2589#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardd4501d72005-07-24 14:27:16 +00002590#ifdef LIBXML_SCHEMATRON_ENABLED
2591 if (wxschematron != NULL) {
2592 xmlSchematronValidCtxtPtr ctxt;
2593 int ret;
Daniel Veillardc740a172005-07-31 12:17:24 +00002594 int flag;
Daniel Veillardd4501d72005-07-24 14:27:16 +00002595
2596 if ((timing) && (!repeat)) {
2597 startTimer();
2598 }
2599
2600 if (debug)
2601 flag = XML_SCHEMATRON_OUT_XML;
Daniel Veillardc740a172005-07-31 12:17:24 +00002602 else
2603 flag = XML_SCHEMATRON_OUT_TEXT;
2604 if (noout)
2605 flag |= XML_SCHEMATRON_OUT_QUIET;
Daniel Veillardd4501d72005-07-24 14:27:16 +00002606 ctxt = xmlSchematronNewValidCtxt(wxschematron, flag);
2607#if 0
2608 xmlSchematronSetValidErrors(ctxt,
2609 (xmlSchematronValidityErrorFunc) fprintf,
2610 (xmlSchematronValidityWarningFunc) fprintf,
2611 stderr);
2612#endif
2613 ret = xmlSchematronValidateDoc(ctxt, doc);
2614 if (ret == 0) {
2615 fprintf(stderr, "%s validates\n", filename);
2616 } else if (ret > 0) {
2617 fprintf(stderr, "%s fails to validate\n", filename);
2618 progresult = XMLLINT_ERR_VALID;
2619 } else {
2620 fprintf(stderr, "%s validation generated an internal error\n",
2621 filename);
2622 progresult = XMLLINT_ERR_VALID;
2623 }
2624 xmlSchematronFreeValidCtxt(ctxt);
2625 if ((timing) && (!repeat)) {
2626 endTimer("Validating");
2627 }
2628 }
2629#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00002630#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard4432df22003-09-28 18:58:27 +00002631 if (relaxngschemas != NULL) {
Daniel Veillard71531f32003-02-05 13:19:53 +00002632 xmlRelaxNGValidCtxtPtr ctxt;
2633 int ret;
2634
Daniel Veillard42f12e92003-03-07 18:32:59 +00002635 if ((timing) && (!repeat)) {
2636 startTimer();
2637 }
2638
Daniel Veillard71531f32003-02-05 13:19:53 +00002639 ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
2640 xmlRelaxNGSetValidErrors(ctxt,
2641 (xmlRelaxNGValidityErrorFunc) fprintf,
2642 (xmlRelaxNGValidityWarningFunc) fprintf,
2643 stderr);
2644 ret = xmlRelaxNGValidateDoc(ctxt, doc);
2645 if (ret == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002646 fprintf(stderr, "%s validates\n", filename);
Daniel Veillard71531f32003-02-05 13:19:53 +00002647 } else if (ret > 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002648 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002649 progresult = XMLLINT_ERR_VALID;
Daniel Veillard71531f32003-02-05 13:19:53 +00002650 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002651 fprintf(stderr, "%s validation generated an internal error\n",
Daniel Veillard71531f32003-02-05 13:19:53 +00002652 filename);
William M. Brack8304d872004-06-08 13:29:32 +00002653 progresult = XMLLINT_ERR_VALID;
Daniel Veillard71531f32003-02-05 13:19:53 +00002654 }
2655 xmlRelaxNGFreeValidCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00002656 if ((timing) && (!repeat)) {
2657 endTimer("Validating");
2658 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002659 } else if (wxschemas != NULL) {
2660 xmlSchemaValidCtxtPtr ctxt;
2661 int ret;
2662
2663 if ((timing) && (!repeat)) {
2664 startTimer();
2665 }
2666
2667 ctxt = xmlSchemaNewValidCtxt(wxschemas);
2668 xmlSchemaSetValidErrors(ctxt,
2669 (xmlSchemaValidityErrorFunc) fprintf,
2670 (xmlSchemaValidityWarningFunc) fprintf,
2671 stderr);
2672 ret = xmlSchemaValidateDoc(ctxt, doc);
2673 if (ret == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002674 fprintf(stderr, "%s validates\n", filename);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002675 } else if (ret > 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002676 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002677 progresult = XMLLINT_ERR_VALID;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002678 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002679 fprintf(stderr, "%s validation generated an internal error\n",
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002680 filename);
William M. Brack8304d872004-06-08 13:29:32 +00002681 progresult = XMLLINT_ERR_VALID;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002682 }
2683 xmlSchemaFreeValidCtxt(ctxt);
2684 if ((timing) && (!repeat)) {
2685 endTimer("Validating");
2686 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002687 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002688#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002689
2690#ifdef LIBXML_DEBUG_ENABLED
2691 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00002692 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002693#endif
2694
2695 /*
2696 * free it.
2697 */
Daniel Veillard48b2f892001-02-25 16:11:03 +00002698 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002699 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002700 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002701 xmlFreeDoc(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +00002702 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002703 endTimer("Freeing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002704 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002705}
2706
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002707/************************************************************************
2708 * *
2709 * Usage and Main *
2710 * *
2711 ************************************************************************/
2712
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002713static void showVersion(const char *name) {
2714 fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
2715 fprintf(stderr, " compiled with: ");
Daniel Veillard4432df22003-09-28 18:58:27 +00002716#ifdef LIBXML_VALID_ENABLED
2717 fprintf(stderr, "DTDValid ");
2718#endif
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002719#ifdef LIBXML_FTP_ENABLED
2720 fprintf(stderr, "FTP ");
2721#endif
2722#ifdef LIBXML_HTTP_ENABLED
2723 fprintf(stderr, "HTTP ");
2724#endif
2725#ifdef LIBXML_HTML_ENABLED
2726 fprintf(stderr, "HTML ");
2727#endif
2728#ifdef LIBXML_C14N_ENABLED
2729 fprintf(stderr, "C14N ");
2730#endif
2731#ifdef LIBXML_CATALOG_ENABLED
2732 fprintf(stderr, "Catalog ");
2733#endif
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002734#ifdef LIBXML_XPATH_ENABLED
2735 fprintf(stderr, "XPath ");
2736#endif
2737#ifdef LIBXML_XPTR_ENABLED
2738 fprintf(stderr, "XPointer ");
2739#endif
2740#ifdef LIBXML_XINCLUDE_ENABLED
2741 fprintf(stderr, "XInclude ");
2742#endif
2743#ifdef LIBXML_ICONV_ENABLED
2744 fprintf(stderr, "Iconv ");
2745#endif
2746#ifdef DEBUG_MEMORY_LOCATION
2747 fprintf(stderr, "MemDebug ");
2748#endif
2749#ifdef LIBXML_UNICODE_ENABLED
2750 fprintf(stderr, "Unicode ");
2751#endif
2752#ifdef LIBXML_REGEXP_ENABLED
2753 fprintf(stderr, "Regexps ");
2754#endif
Daniel Veillard465a0002005-08-22 12:07:04 +00002755#ifdef LIBXML_EXPR_ENABLED
2756 fprintf(stderr, "Expr ");
2757#endif
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002758#ifdef LIBXML_AUTOMATA_ENABLED
2759 fprintf(stderr, "Automata ");
2760#endif
2761#ifdef LIBXML_SCHEMAS_ENABLED
2762 fprintf(stderr, "Schemas ");
2763#endif
Daniel Veillardce1648b2005-01-04 15:10:22 +00002764#ifdef LIBXML_MODULES_ENABLED
2765 fprintf(stderr, "Modules ");
2766#endif
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002767 fprintf(stderr, "\n");
2768}
2769
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002770static void usage(const char *name) {
2771 printf("Usage : %s [options] XMLfiles ...\n", name);
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002772#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002773 printf("\tParse the XML files and output the result of the parsing\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002774#else
2775 printf("\tParse the XML files\n");
2776#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002777 printf("\t--version : display the version of the XML library used\n");
2778#ifdef LIBXML_DEBUG_ENABLED
2779 printf("\t--debug : dump a debug tree of the in-memory document\n");
2780 printf("\t--shell : run a navigating shell\n");
2781 printf("\t--debugent : debug the entities defined in the document\n");
Daniel Veillard8326e732003-01-07 00:19:07 +00002782#else
Daniel Veillard81273902003-09-30 00:43:48 +00002783#ifdef LIBXML_READER_ENABLED
Daniel Veillard8326e732003-01-07 00:19:07 +00002784 printf("\t--debug : dump the nodes content when using --stream\n");
Daniel Veillard81273902003-09-30 00:43:48 +00002785#endif /* LIBXML_READER_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002786#endif
Daniel Veillard652327a2003-09-29 18:02:38 +00002787#ifdef LIBXML_TREE_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002788 printf("\t--copy : used to test the internal copy implementation\n");
Daniel Veillard652327a2003-09-29 18:02:38 +00002789#endif /* LIBXML_TREE_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002790 printf("\t--recover : output what was parsable on broken XML documents\n");
2791 printf("\t--noent : substitute entity references by their value\n");
2792 printf("\t--noout : don't output the result tree\n");
Daniel Veillard0bff36d2004-08-31 09:37:03 +00002793 printf("\t--path 'paths': provide a set of paths for resources\n");
2794 printf("\t--load-trace : print trace of all external entites loaded\n");
Daniel Veillarde8b09e42003-05-13 22:14:13 +00002795 printf("\t--nonet : refuse to fetch DTDs or entities over network\n");
Daniel Veillard8874b942005-08-25 13:19:21 +00002796 printf("\t--nocompact : do not generate compact text nodes\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002797 printf("\t--htmlout : output results as HTML\n");
Daniel Veillard05c13a22001-09-09 08:38:09 +00002798 printf("\t--nowrap : do not put HTML doc wrapper\n");
Daniel Veillard4432df22003-09-28 18:58:27 +00002799#ifdef LIBXML_VALID_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002800 printf("\t--valid : validate the document in addition to std well-formed check\n");
2801 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
2802 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
Daniel Veillard66f68e72003-08-18 16:39:51 +00002803 printf("\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
Daniel Veillard4432df22003-09-28 18:58:27 +00002804#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002805 printf("\t--timing : print some timings\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002806 printf("\t--output file or -o file: save to a given file\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002807 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
2808 printf("\t--insert : ad-hoc test for valid insertions\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002809#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002810#ifdef HAVE_ZLIB_H
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002811 printf("\t--compress : turn on gzip compression of output\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002812#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002813#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002814#ifdef LIBXML_HTML_ENABLED
2815 printf("\t--html : use the HTML parser\n");
Daniel Veillard42fd4122003-11-04 08:47:48 +00002816 printf("\t--xmlout : force to use the XML serializer when using --html\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002817#endif
Daniel Veillard73b013f2003-09-30 12:36:01 +00002818#ifdef LIBXML_PUSH_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002819 printf("\t--push : use the push mode of the parser\n");
Daniel Veillard73b013f2003-09-30 12:36:01 +00002820#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002821#ifdef HAVE_SYS_MMAN_H
2822 printf("\t--memory : parse from memory\n");
2823#endif
Daniel Veillard87076042004-05-03 22:54:49 +00002824 printf("\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002825 printf("\t--nowarning : do not emit warnings from parser/validator\n");
2826 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
Daniel Veillarddca8cc72003-09-26 13:53:14 +00002827 printf("\t--nocdata : replace cdata section with text nodes\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002828#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard90493a92001-08-14 14:12:47 +00002829 printf("\t--format : reformat/reindent the input\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002830 printf("\t--encode encoding : output in the given encoding\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002831 printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
2832#endif /* LIBXML_OUTPUT_ENABLED */
Aleksey Sanin2650df12005-06-06 17:16:50 +00002833 printf("\t--c14n : save in W3C canonical format (with comments)\n");
2834 printf("\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n");
Daniel Veillard25048d82004-08-14 22:37:54 +00002835#ifdef LIBXML_C14N_ENABLED
2836#endif /* LIBXML_C14N_ENABLED */
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002837 printf("\t--nsclean : remove redundant namespace declarations\n");
2838 printf("\t--testIO : test user I/O support\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002839#ifdef LIBXML_CATALOG_ENABLED
Daniel Veillardbd9b0e82001-11-26 10:32:08 +00002840 printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
2841 printf("\t otherwise XML Catalogs starting from \n");
Daniel Veillardb3de70c2003-12-02 22:32:15 +00002842 printf("\t %s are activated by default\n", XML_XML_DEFAULT_CATALOG);
Daniel Veillard05c13a22001-09-09 08:38:09 +00002843 printf("\t--nocatalogs: deactivate all catalogs\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002844#endif
2845 printf("\t--auto : generate a small doc on the fly\n");
2846#ifdef LIBXML_XINCLUDE_ENABLED
2847 printf("\t--xinclude : do XInclude processing\n");
Daniel Veillardc14c3892004-08-16 12:34:50 +00002848 printf("\t--noxincludenode : same but do not generate XInclude nodes\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002849#endif
Daniel Veillardcbaf3992001-12-31 16:16:02 +00002850 printf("\t--loaddtd : fetch external DTD\n");
Daniel Veillard48da9102001-08-07 01:10:10 +00002851 printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
Daniel Veillard81273902003-09-30 00:43:48 +00002852#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00002853 printf("\t--stream : use the streaming interface to process very large files\n");
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002854 printf("\t--walker : create a reader and walk though the resulting doc\n");
Daniel Veillard81273902003-09-30 00:43:48 +00002855#endif /* LIBXML_READER_ENABLED */
Daniel Veillardb3de70c2003-12-02 22:32:15 +00002856#ifdef LIBXML_PATTERN_ENABLED
2857 printf("\t--pattern pattern_value : test the pattern support\n");
2858#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00002859 printf("\t--chkregister : verify the node registration code\n");
Daniel Veillardef4d3bc2003-02-07 12:38:22 +00002860#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard71531f32003-02-05 13:19:53 +00002861 printf("\t--relaxng schema : do RelaxNG validation against the schema\n");
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002862 printf("\t--schema schema : do validation against the WXS schema\n");
Daniel Veillard71531f32003-02-05 13:19:53 +00002863#endif
Daniel Veillarde70375c2005-07-30 21:09:12 +00002864#ifdef LIBXML_SCHEMATRON_ENABLED
2865 printf("\t--schematron schema : do validation against a schematron\n");
2866#endif
Daniel Veillard971771e2005-07-09 17:32:57 +00002867#ifdef LIBXML_SAX1_ENABLED
2868 printf("\t--sax1: use the old SAX1 interfaces for processing\n");
2869#endif
2870 printf("\t--sax: do not build a tree but work just at the SAX level\n");
2871
Daniel Veillarda42f25f2002-01-25 14:15:40 +00002872 printf("\nLibxml project home page: http://xmlsoft.org/\n");
2873 printf("To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002874}
Daniel Veillard8a1b1852003-01-05 22:37:17 +00002875
2876static void registerNode(xmlNodePtr node)
2877{
2878 node->_private = malloc(sizeof(long));
2879 *(long*)node->_private = (long) 0x81726354;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00002880 nbregister++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00002881}
2882
2883static void deregisterNode(xmlNodePtr node)
2884{
2885 assert(node->_private != NULL);
2886 assert(*(long*)node->_private == (long) 0x81726354);
2887 free(node->_private);
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00002888 nbregister--;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00002889}
2890
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002891int
2892main(int argc, char **argv) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00002893 int i, acount;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002894 int files = 0;
Daniel Veillard845cce42002-01-09 11:51:37 +00002895 int version = 0;
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00002896 const char* indent;
2897
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002898 if (argc <= 1) {
2899 usage(argv[0]);
2900 return(1);
2901 }
Daniel Veillardbe803962000-06-28 23:40:59 +00002902 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002903 for (i = 1; i < argc ; i++) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002904 if (!strcmp(argv[i], "-"))
2905 break;
2906
2907 if (argv[i][0] != '-')
2908 continue;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002909 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
2910 debug++;
Daniel Veillard56ada1d2003-01-07 11:17:25 +00002911 else
2912#ifdef LIBXML_DEBUG_ENABLED
2913 if ((!strcmp(argv[i], "-shell")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002914 (!strcmp(argv[i], "--shell"))) {
2915 shell++;
2916 noout = 1;
2917 } else
2918#endif
Daniel Veillard652327a2003-09-29 18:02:38 +00002919#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002920 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
2921 copy++;
Daniel Veillard652327a2003-09-29 18:02:38 +00002922 else
2923#endif /* LIBXML_TREE_ENABLED */
2924 if ((!strcmp(argv[i], "-recover")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002925 (!strcmp(argv[i], "--recover"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002926 recovery++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002927 options |= XML_PARSE_RECOVER;
2928 } else if ((!strcmp(argv[i], "-noent")) ||
2929 (!strcmp(argv[i], "--noent"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002930 noent++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002931 options |= XML_PARSE_NOENT;
Daniel Veillarddca8cc72003-09-26 13:53:14 +00002932 } else if ((!strcmp(argv[i], "-nsclean")) ||
2933 (!strcmp(argv[i], "--nsclean"))) {
2934 options |= XML_PARSE_NSCLEAN;
2935 } else if ((!strcmp(argv[i], "-nocdata")) ||
2936 (!strcmp(argv[i], "--nocdata"))) {
2937 options |= XML_PARSE_NOCDATA;
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002938 } else if ((!strcmp(argv[i], "-nodict")) ||
2939 (!strcmp(argv[i], "--nodict"))) {
2940 options |= XML_PARSE_NODICT;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002941 } else if ((!strcmp(argv[i], "-version")) ||
Daniel Veillard845cce42002-01-09 11:51:37 +00002942 (!strcmp(argv[i], "--version"))) {
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002943 showVersion(argv[0]);
Daniel Veillard845cce42002-01-09 11:51:37 +00002944 version = 1;
2945 } else if ((!strcmp(argv[i], "-noout")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002946 (!strcmp(argv[i], "--noout")))
2947 noout++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002948#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002949 else if ((!strcmp(argv[i], "-o")) ||
2950 (!strcmp(argv[i], "-output")) ||
2951 (!strcmp(argv[i], "--output"))) {
2952 i++;
Daniel Veillard6e4f1c02002-04-09 09:55:20 +00002953 output = argv[i];
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002954 }
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002955#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002956 else if ((!strcmp(argv[i], "-htmlout")) ||
2957 (!strcmp(argv[i], "--htmlout")))
2958 htmlout++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002959 else if ((!strcmp(argv[i], "-nowrap")) ||
2960 (!strcmp(argv[i], "--nowrap")))
2961 nowrap++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002962#ifdef LIBXML_HTML_ENABLED
2963 else if ((!strcmp(argv[i], "-html")) ||
2964 (!strcmp(argv[i], "--html"))) {
2965 html++;
2966 }
Daniel Veillard42fd4122003-11-04 08:47:48 +00002967 else if ((!strcmp(argv[i], "-xmlout")) ||
2968 (!strcmp(argv[i], "--xmlout"))) {
2969 xmlout++;
2970 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002971#endif /* LIBXML_HTML_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002972 else if ((!strcmp(argv[i], "-loaddtd")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002973 (!strcmp(argv[i], "--loaddtd"))) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002974 loaddtd++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002975 options |= XML_PARSE_DTDLOAD;
2976 } else if ((!strcmp(argv[i], "-dtdattr")) ||
Daniel Veillard48da9102001-08-07 01:10:10 +00002977 (!strcmp(argv[i], "--dtdattr"))) {
2978 loaddtd++;
2979 dtdattrs++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002980 options |= XML_PARSE_DTDATTR;
Daniel Veillard4432df22003-09-28 18:58:27 +00002981 }
2982#ifdef LIBXML_VALID_ENABLED
2983 else if ((!strcmp(argv[i], "-valid")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002984 (!strcmp(argv[i], "--valid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002985 valid++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002986 options |= XML_PARSE_DTDVALID;
2987 } else if ((!strcmp(argv[i], "-postvalid")) ||
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002988 (!strcmp(argv[i], "--postvalid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002989 postvalid++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002990 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00002991 options |= XML_PARSE_DTDLOAD;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002992 } else if ((!strcmp(argv[i], "-dtdvalid")) ||
Daniel Veillardcd429612000-10-11 15:57:05 +00002993 (!strcmp(argv[i], "--dtdvalid"))) {
2994 i++;
2995 dtdvalid = argv[i];
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002996 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00002997 options |= XML_PARSE_DTDLOAD;
Daniel Veillard66f68e72003-08-18 16:39:51 +00002998 } else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
2999 (!strcmp(argv[i], "--dtdvalidfpi"))) {
3000 i++;
3001 dtdvalidfpi = argv[i];
3002 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003003 options |= XML_PARSE_DTDLOAD;
Daniel Veillardcd429612000-10-11 15:57:05 +00003004 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003005#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard29e43992001-12-13 22:21:58 +00003006 else if ((!strcmp(argv[i], "-dropdtd")) ||
3007 (!strcmp(argv[i], "--dropdtd")))
3008 dropdtd++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003009 else if ((!strcmp(argv[i], "-insert")) ||
3010 (!strcmp(argv[i], "--insert")))
3011 insert++;
Daniel Veillard48b2f892001-02-25 16:11:03 +00003012 else if ((!strcmp(argv[i], "-timing")) ||
3013 (!strcmp(argv[i], "--timing")))
3014 timing++;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00003015 else if ((!strcmp(argv[i], "-auto")) ||
3016 (!strcmp(argv[i], "--auto")))
3017 generate++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003018 else if ((!strcmp(argv[i], "-repeat")) ||
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00003019 (!strcmp(argv[i], "--repeat"))) {
3020 if (repeat)
3021 repeat *= 10;
3022 else
3023 repeat = 100;
Daniel Veillard73b013f2003-09-30 12:36:01 +00003024 }
3025#ifdef LIBXML_PUSH_ENABLED
3026 else if ((!strcmp(argv[i], "-push")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003027 (!strcmp(argv[i], "--push")))
3028 push++;
Daniel Veillard73b013f2003-09-30 12:36:01 +00003029#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillard46e370e2000-07-21 20:32:03 +00003030#ifdef HAVE_SYS_MMAN_H
3031 else if ((!strcmp(argv[i], "-memory")) ||
3032 (!strcmp(argv[i], "--memory")))
3033 memory++;
3034#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +00003035 else if ((!strcmp(argv[i], "-testIO")) ||
3036 (!strcmp(argv[i], "--testIO")))
3037 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003038#ifdef LIBXML_XINCLUDE_ENABLED
3039 else if ((!strcmp(argv[i], "-xinclude")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003040 (!strcmp(argv[i], "--xinclude"))) {
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003041 xinclude++;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003042 options |= XML_PARSE_XINCLUDE;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003043 }
Daniel Veillardc14c3892004-08-16 12:34:50 +00003044 else if ((!strcmp(argv[i], "-noxincludenode")) ||
3045 (!strcmp(argv[i], "--noxincludenode"))) {
3046 xinclude++;
3047 options |= XML_PARSE_XINCLUDE;
3048 options |= XML_PARSE_NOXINCNODE;
3049 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003050#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003051#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003052#ifdef HAVE_ZLIB_H
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003053 else if ((!strcmp(argv[i], "-compress")) ||
3054 (!strcmp(argv[i], "--compress"))) {
3055 compress++;
3056 xmlSetCompressMode(9);
3057 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003058#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003059#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003060 else if ((!strcmp(argv[i], "-nowarning")) ||
3061 (!strcmp(argv[i], "--nowarning"))) {
3062 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003063 xmlPedanticParserDefault(0);
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003064 options |= XML_PARSE_NOWARNING;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003065 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003066 else if ((!strcmp(argv[i], "-pedantic")) ||
3067 (!strcmp(argv[i], "--pedantic"))) {
3068 xmlGetWarningsDefaultValue = 1;
3069 xmlPedanticParserDefault(1);
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003070 options |= XML_PARSE_PEDANTIC;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003071 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00003072#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003073 else if ((!strcmp(argv[i], "-debugent")) ||
3074 (!strcmp(argv[i], "--debugent"))) {
3075 debugent++;
3076 xmlParserDebugEntities = 1;
3077 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00003078#endif
Daniel Veillard25048d82004-08-14 22:37:54 +00003079#ifdef LIBXML_C14N_ENABLED
3080 else if ((!strcmp(argv[i], "-c14n")) ||
3081 (!strcmp(argv[i], "--c14n"))) {
3082 canonical++;
3083 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
3084 }
Aleksey Sanin2650df12005-06-06 17:16:50 +00003085 else if ((!strcmp(argv[i], "-exc-c14n")) ||
3086 (!strcmp(argv[i], "--exc-c14n"))) {
3087 exc_canonical++;
3088 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
3089 }
Daniel Veillard25048d82004-08-14 22:37:54 +00003090#endif
Daniel Veillard81418e32001-05-22 15:08:55 +00003091#ifdef LIBXML_CATALOG_ENABLED
3092 else if ((!strcmp(argv[i], "-catalogs")) ||
3093 (!strcmp(argv[i], "--catalogs"))) {
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003094 catalogs++;
3095 } else if ((!strcmp(argv[i], "-nocatalogs")) ||
3096 (!strcmp(argv[i], "--nocatalogs"))) {
3097 nocatalogs++;
Daniel Veillard81418e32001-05-22 15:08:55 +00003098 }
3099#endif
Daniel Veillardbe803962000-06-28 23:40:59 +00003100 else if ((!strcmp(argv[i], "-encode")) ||
3101 (!strcmp(argv[i], "--encode"))) {
3102 i++;
3103 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003104 /*
3105 * OK it's for testing purposes
3106 */
3107 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +00003108 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003109 else if ((!strcmp(argv[i], "-noblanks")) ||
3110 (!strcmp(argv[i], "--noblanks"))) {
3111 noblanks++;
3112 xmlKeepBlanksDefault(0);
Daniel Veillard90493a92001-08-14 14:12:47 +00003113 }
Daniel Veillard87076042004-05-03 22:54:49 +00003114 else if ((!strcmp(argv[i], "-maxmem")) ||
3115 (!strcmp(argv[i], "--maxmem"))) {
3116 i++;
3117 if (sscanf(argv[i], "%d", &maxmem) == 1) {
3118 xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc,
3119 myStrdupFunc);
3120 } else {
3121 maxmem = 0;
3122 }
3123 }
Daniel Veillard90493a92001-08-14 14:12:47 +00003124 else if ((!strcmp(argv[i], "-format")) ||
3125 (!strcmp(argv[i], "--format"))) {
3126 noblanks++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003127#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard90493a92001-08-14 14:12:47 +00003128 format++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003129#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard90493a92001-08-14 14:12:47 +00003130 xmlKeepBlanksDefault(0);
Daniel Veillard7704fb12003-01-03 16:19:51 +00003131 }
Daniel Veillard81273902003-09-30 00:43:48 +00003132#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003133 else if ((!strcmp(argv[i], "-stream")) ||
3134 (!strcmp(argv[i], "--stream"))) {
3135 stream++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003136 }
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003137 else if ((!strcmp(argv[i], "-walker")) ||
3138 (!strcmp(argv[i], "--walker"))) {
3139 walker++;
3140 noout++;
3141 }
Daniel Veillard81273902003-09-30 00:43:48 +00003142#endif /* LIBXML_READER_ENABLED */
3143#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +00003144 else if ((!strcmp(argv[i], "-sax1")) ||
3145 (!strcmp(argv[i], "--sax1"))) {
3146 sax1++;
3147 }
Daniel Veillard81273902003-09-30 00:43:48 +00003148#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003149 else if ((!strcmp(argv[i], "-sax")) ||
3150 (!strcmp(argv[i], "--sax"))) {
3151 sax++;
3152 }
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003153 else if ((!strcmp(argv[i], "-chkregister")) ||
3154 (!strcmp(argv[i], "--chkregister"))) {
3155 chkregister++;
Daniel Veillard71531f32003-02-05 13:19:53 +00003156#ifdef LIBXML_SCHEMAS_ENABLED
3157 } else if ((!strcmp(argv[i], "-relaxng")) ||
3158 (!strcmp(argv[i], "--relaxng"))) {
3159 i++;
3160 relaxng = argv[i];
3161 noent++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003162 options |= XML_PARSE_NOENT;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003163 } else if ((!strcmp(argv[i], "-schema")) ||
3164 (!strcmp(argv[i], "--schema"))) {
3165 i++;
3166 schema = argv[i];
3167 noent++;
Daniel Veillard71531f32003-02-05 13:19:53 +00003168#endif
Daniel Veillardd4501d72005-07-24 14:27:16 +00003169#ifdef LIBXML_SCHEMATRON_ENABLED
3170 } else if ((!strcmp(argv[i], "-schematron")) ||
3171 (!strcmp(argv[i], "--schematron"))) {
3172 i++;
3173 schematron = argv[i];
3174 noent++;
3175#endif
Daniel Veillarde8b09e42003-05-13 22:14:13 +00003176 } else if ((!strcmp(argv[i], "-nonet")) ||
3177 (!strcmp(argv[i], "--nonet"))) {
Daniel Veillard61b93382003-11-03 14:28:31 +00003178 options |= XML_PARSE_NONET;
Daniel Veillard8874b942005-08-25 13:19:21 +00003179 } else if ((!strcmp(argv[i], "-nocompact")) ||
3180 (!strcmp(argv[i], "--nocompact"))) {
3181 options &= ~XML_PARSE_COMPACT;
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003182 } else if ((!strcmp(argv[i], "-load-trace")) ||
3183 (!strcmp(argv[i], "--load-trace"))) {
3184 load_trace++;
3185 } else if ((!strcmp(argv[i], "-path")) ||
3186 (!strcmp(argv[i], "--path"))) {
3187 i++;
3188 parsePath(BAD_CAST argv[i]);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003189#ifdef LIBXML_PATTERN_ENABLED
3190 } else if ((!strcmp(argv[i], "-pattern")) ||
3191 (!strcmp(argv[i], "--pattern"))) {
3192 i++;
3193 pattern = argv[i];
3194#endif
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003195 } else {
3196 fprintf(stderr, "Unknown option %s\n", argv[i]);
3197 usage(argv[0]);
3198 return(1);
3199 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003200 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003201
3202#ifdef LIBXML_CATALOG_ENABLED
3203 if (nocatalogs == 0) {
3204 if (catalogs) {
3205 const char *catal;
3206
3207 catal = getenv("SGML_CATALOG_FILES");
Daniel Veillard6c5f9d12001-08-25 13:33:14 +00003208 if (catal != NULL) {
3209 xmlLoadCatalogs(catal);
3210 } else {
3211 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
3212 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003213 }
3214 }
3215#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003216
Daniel Veillard81273902003-09-30 00:43:48 +00003217#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +00003218 if (sax1)
3219 xmlSAXDefaultVersion(1);
3220 else
3221 xmlSAXDefaultVersion(2);
Daniel Veillard81273902003-09-30 00:43:48 +00003222#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillard07cb8222003-09-10 10:51:05 +00003223
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003224 if (chkregister) {
3225 xmlRegisterNodeDefault(registerNode);
3226 xmlDeregisterNodeDefault(deregisterNode);
3227 }
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00003228
3229 indent = getenv("XMLLINT_INDENT");
3230 if(indent != NULL) {
3231 xmlTreeIndentString = indent;
3232 }
3233
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003234
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003235 defaultEntityLoader = xmlGetExternalEntityLoader();
3236 xmlSetExternalEntityLoader(xmllintExternalEntityLoader);
3237
Daniel Veillardd9bad132001-07-23 19:39:43 +00003238 xmlLineNumbersDefault(1);
Daniel Veillard48da9102001-08-07 01:10:10 +00003239 if (loaddtd != 0)
3240 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
3241 if (dtdattrs)
3242 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003243 if (noent != 0) xmlSubstituteEntitiesDefault(1);
Daniel Veillard4432df22003-09-28 18:58:27 +00003244#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003245 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
Daniel Veillard4432df22003-09-28 18:58:27 +00003246#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003247 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003248 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003249 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003250 xmlGenericError(xmlGenericErrorContext,
3251 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
3252 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003253 "<html><head><title>%s output</title></head>\n",
3254 argv[0]);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003255 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003256 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
3257 argv[0]);
3258 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003259
Daniel Veillardd4501d72005-07-24 14:27:16 +00003260#ifdef LIBXML_SCHEMATRON_ENABLED
3261 if ((schematron != NULL) && (sax == 0)
3262#ifdef LIBXML_READER_ENABLED
3263 && (stream == 0)
3264#endif /* LIBXML_READER_ENABLED */
3265 ) {
3266 xmlSchematronParserCtxtPtr ctxt;
3267
3268 /* forces loading the DTDs */
3269 xmlLoadExtDtdDefaultValue |= 1;
3270 options |= XML_PARSE_DTDLOAD;
3271 if (timing) {
3272 startTimer();
3273 }
3274 ctxt = xmlSchematronNewParserCtxt(schematron);
3275#if 0
3276 xmlSchematronSetParserErrors(ctxt,
3277 (xmlSchematronValidityErrorFunc) fprintf,
3278 (xmlSchematronValidityWarningFunc) fprintf,
3279 stderr);
3280#endif
3281 wxschematron = xmlSchematronParse(ctxt);
3282 if (wxschematron == NULL) {
3283 xmlGenericError(xmlGenericErrorContext,
3284 "Schematron schema %s failed to compile\n", schematron);
3285 progresult = XMLLINT_ERR_SCHEMACOMP;
3286 schematron = NULL;
3287 }
3288 xmlSchematronFreeParserCtxt(ctxt);
3289 if (timing) {
3290 endTimer("Compiling the schemas");
3291 }
3292 }
3293#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00003294#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003295 if ((relaxng != NULL) && (sax == 0)
Daniel Veillard81273902003-09-30 00:43:48 +00003296#ifdef LIBXML_READER_ENABLED
3297 && (stream == 0)
3298#endif /* LIBXML_READER_ENABLED */
3299 ) {
Daniel Veillard71531f32003-02-05 13:19:53 +00003300 xmlRelaxNGParserCtxtPtr ctxt;
3301
Daniel Veillardce192eb2003-04-16 15:58:05 +00003302 /* forces loading the DTDs */
3303 xmlLoadExtDtdDefaultValue |= 1;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003304 options |= XML_PARSE_DTDLOAD;
Daniel Veillard42f12e92003-03-07 18:32:59 +00003305 if (timing) {
3306 startTimer();
3307 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003308 ctxt = xmlRelaxNGNewParserCtxt(relaxng);
3309 xmlRelaxNGSetParserErrors(ctxt,
3310 (xmlRelaxNGValidityErrorFunc) fprintf,
3311 (xmlRelaxNGValidityWarningFunc) fprintf,
3312 stderr);
3313 relaxngschemas = xmlRelaxNGParse(ctxt);
Daniel Veillardce192eb2003-04-16 15:58:05 +00003314 if (relaxngschemas == NULL) {
3315 xmlGenericError(xmlGenericErrorContext,
3316 "Relax-NG schema %s failed to compile\n", relaxng);
William M. Brack8304d872004-06-08 13:29:32 +00003317 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillardce192eb2003-04-16 15:58:05 +00003318 relaxng = NULL;
3319 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003320 xmlRelaxNGFreeParserCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00003321 if (timing) {
3322 endTimer("Compiling the schemas");
3323 }
Daniel Veillardebe25d42004-03-25 09:35:49 +00003324 } else if ((schema != NULL)
3325#ifdef LIBXML_READER_ENABLED
Daniel Veillardf10ae122005-07-10 19:03:16 +00003326 && (stream == 0)
Daniel Veillardebe25d42004-03-25 09:35:49 +00003327#endif
3328 ) {
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003329 xmlSchemaParserCtxtPtr ctxt;
3330
3331 if (timing) {
3332 startTimer();
3333 }
3334 ctxt = xmlSchemaNewParserCtxt(schema);
3335 xmlSchemaSetParserErrors(ctxt,
3336 (xmlSchemaValidityErrorFunc) fprintf,
3337 (xmlSchemaValidityWarningFunc) fprintf,
3338 stderr);
3339 wxschemas = xmlSchemaParse(ctxt);
3340 if (wxschemas == NULL) {
3341 xmlGenericError(xmlGenericErrorContext,
3342 "WXS schema %s failed to compile\n", schema);
William M. Brack8304d872004-06-08 13:29:32 +00003343 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003344 schema = NULL;
3345 }
3346 xmlSchemaFreeParserCtxt(ctxt);
3347 if (timing) {
3348 endTimer("Compiling the schemas");
3349 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003350 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003351#endif /* LIBXML_SCHEMAS_ENABLED */
3352#ifdef LIBXML_PATTERN_ENABLED
Daniel Veillard39e5c892005-07-03 22:48:50 +00003353 if ((pattern != NULL)
Daniel Veillardc9352532005-07-04 14:25:34 +00003354#ifdef LIBXML_READER_ENABLED
Daniel Veillard39e5c892005-07-03 22:48:50 +00003355 && (walker == 0)
3356#endif
3357 ) {
Daniel Veillardffa7b7e2003-12-05 16:10:21 +00003358 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003359 if (patternc == NULL) {
3360 xmlGenericError(xmlGenericErrorContext,
3361 "Pattern %s failed to compile\n", pattern);
William M. Brack8304d872004-06-08 13:29:32 +00003362 progresult = XMLLINT_ERR_SCHEMAPAT;
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003363 pattern = NULL;
3364 }
3365 }
3366#endif /* LIBXML_PATTERN_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003367 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +00003368 if ((!strcmp(argv[i], "-encode")) ||
3369 (!strcmp(argv[i], "--encode"))) {
3370 i++;
3371 continue;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003372 } else if ((!strcmp(argv[i], "-o")) ||
3373 (!strcmp(argv[i], "-output")) ||
3374 (!strcmp(argv[i], "--output"))) {
3375 i++;
3376 continue;
Daniel Veillardbe803962000-06-28 23:40:59 +00003377 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003378#ifdef LIBXML_VALID_ENABLED
Daniel Veillardcd429612000-10-11 15:57:05 +00003379 if ((!strcmp(argv[i], "-dtdvalid")) ||
3380 (!strcmp(argv[i], "--dtdvalid"))) {
3381 i++;
3382 continue;
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003383 }
3384 if ((!strcmp(argv[i], "-path")) ||
3385 (!strcmp(argv[i], "--path"))) {
3386 i++;
3387 continue;
Daniel Veillardcd429612000-10-11 15:57:05 +00003388 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00003389 if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3390 (!strcmp(argv[i], "--dtdvalidfpi"))) {
3391 i++;
3392 continue;
3393 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003394#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard71531f32003-02-05 13:19:53 +00003395 if ((!strcmp(argv[i], "-relaxng")) ||
3396 (!strcmp(argv[i], "--relaxng"))) {
3397 i++;
3398 continue;
3399 }
Daniel Veillard87076042004-05-03 22:54:49 +00003400 if ((!strcmp(argv[i], "-maxmem")) ||
3401 (!strcmp(argv[i], "--maxmem"))) {
3402 i++;
3403 continue;
3404 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003405 if ((!strcmp(argv[i], "-schema")) ||
3406 (!strcmp(argv[i], "--schema"))) {
3407 i++;
3408 continue;
3409 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00003410 if ((!strcmp(argv[i], "-schematron")) ||
3411 (!strcmp(argv[i], "--schematron"))) {
3412 i++;
3413 continue;
3414 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003415#ifdef LIBXML_PATTERN_ENABLED
3416 if ((!strcmp(argv[i], "-pattern")) ||
3417 (!strcmp(argv[i], "--pattern"))) {
3418 i++;
3419 continue;
3420 }
3421#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00003422 if ((timing) && (repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00003423 startTimer();
Daniel Veillardcbaf3992001-12-31 16:16:02 +00003424 /* Remember file names. "-" means stdin. <sven@zen.org> */
Daniel Veillard4a6845d2001-01-03 13:32:39 +00003425 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003426 if (repeat) {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003427 xmlParserCtxtPtr ctxt = NULL;
3428
3429 for (acount = 0;acount < repeat;acount++) {
Daniel Veillard81273902003-09-30 00:43:48 +00003430#ifdef LIBXML_READER_ENABLED
Daniel Veillard198c1bf2003-10-20 17:07:41 +00003431 if (stream != 0) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00003432 streamFile(argv[i]);
Daniel Veillard198c1bf2003-10-20 17:07:41 +00003433 } else {
Daniel Veillard81273902003-09-30 00:43:48 +00003434#endif /* LIBXML_READER_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003435 if (sax) {
3436 testSAX(argv[i]);
3437 } else {
3438 if (ctxt == NULL)
3439 ctxt = xmlNewParserCtxt();
3440 parseAndPrintFile(argv[i], ctxt);
3441 }
Daniel Veillard81273902003-09-30 00:43:48 +00003442#ifdef LIBXML_READER_ENABLED
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003443 }
Daniel Veillard81273902003-09-30 00:43:48 +00003444#endif /* LIBXML_READER_ENABLED */
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003445 }
3446 if (ctxt != NULL)
3447 xmlFreeParserCtxt(ctxt);
Daniel Veillard7704fb12003-01-03 16:19:51 +00003448 } else {
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003449 nbregister = 0;
3450
Daniel Veillard81273902003-09-30 00:43:48 +00003451#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003452 if (stream != 0)
3453 streamFile(argv[i]);
3454 else
Daniel Veillard81273902003-09-30 00:43:48 +00003455#endif /* LIBXML_READER_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003456 if (sax) {
3457 testSAX(argv[i]);
3458 } else {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003459 parseAndPrintFile(argv[i], NULL);
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003460 }
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003461
3462 if ((chkregister) && (nbregister != 0)) {
3463 fprintf(stderr, "Registration count off: %d\n", nbregister);
William M. Brack8304d872004-06-08 13:29:32 +00003464 progresult = XMLLINT_ERR_RDREGIS;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003465 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00003466 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003467 files ++;
Daniel Veillarda7866932001-12-04 13:14:44 +00003468 if ((timing) && (repeat)) {
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00003469 endTimer("%d iterations", repeat);
Daniel Veillarda7866932001-12-04 13:14:44 +00003470 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00003471 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003472 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00003473 if (generate)
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003474 parseAndPrintFile(NULL, NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003475 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003476 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003477 }
Daniel Veillard845cce42002-01-09 11:51:37 +00003478 if ((files == 0) && (!generate) && (version == 0)) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003479 usage(argv[0]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003480 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00003481#ifdef LIBXML_SCHEMATRON_ENABLED
3482 if (wxschematron != NULL)
3483 xmlSchematronFree(wxschematron);
3484#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00003485#ifdef LIBXML_SCHEMAS_ENABLED
3486 if (relaxngschemas != NULL)
3487 xmlRelaxNGFree(relaxngschemas);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003488 if (wxschemas != NULL)
3489 xmlSchemaFree(wxschemas);
Daniel Veillard71531f32003-02-05 13:19:53 +00003490 xmlRelaxNGCleanupTypes();
3491#endif
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003492#ifdef LIBXML_PATTERN_ENABLED
3493 if (patternc != NULL)
3494 xmlFreePattern(patternc);
3495#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003496 xmlCleanupParser();
3497 xmlMemoryDump();
3498
Daniel Veillardf7cd4812001-02-23 18:44:52 +00003499 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003500}
Daniel Veillard88a172f2000-08-04 18:23:10 +00003501