blob: 2f77607b507fd02ebeb3763eab1a4b67898851e5 [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>
34#undef SOCKLEN_T
35#define SOCKLEN_T unsigned int
36#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 Veillard71531f32003-02-05 13:19:53 +000088#ifdef LIBXML_SCHEMAS_ENABLED
89#include <libxml/relaxng.h>
Daniel Veillard75bb3bb2003-05-12 15:25:56 +000090#include <libxml/xmlschemas.h>
Daniel Veillard71531f32003-02-05 13:19:53 +000091#endif
Daniel Veillardb3de70c2003-12-02 22:32:15 +000092#ifdef LIBXML_PATTERN_ENABLED
93#include <libxml/pattern.h>
94#endif
Daniel Veillard6ebf3c42004-08-22 13:11:39 +000095#ifdef LIBXML_C14N_ENABLED
96#include <libxml/c14n.h>
97#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000098
Daniel Veillard3be27512003-01-26 19:49:04 +000099#ifndef XML_XML_DEFAULT_CATALOG
100#define XML_XML_DEFAULT_CATALOG "file:///etc/xml/catalog"
101#endif
102
William M. Brack8304d872004-06-08 13:29:32 +0000103typedef enum {
104 XMLLINT_RETURN_OK = 0, /* No error */
105 XMLLINT_ERR_UNCLASS, /* Unclassified */
106 XMLLINT_ERR_DTD, /* Error in DTD */
107 XMLLINT_ERR_VALID, /* Validation error */
108 XMLLINT_ERR_RDFILE, /* CtxtReadFile error */
109 XMLLINT_ERR_SCHEMACOMP, /* Schema compilation */
110 XMLLINT_ERR_OUT, /* Error writing output */
111 XMLLINT_ERR_SCHEMAPAT, /* Error in schema pattern */
112 XMLLINT_ERR_RDREGIS, /* Error in Reader registration */
113 XMLLINT_ERR_MEM /* Out of memory error */
114} xmllintReturnCode;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000115#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000116static int shell = 0;
117static int debugent = 0;
118#endif
Daniel Veillard8326e732003-01-07 00:19:07 +0000119static int debug = 0;
Daniel Veillard87076042004-05-03 22:54:49 +0000120static int maxmem = 0;
Daniel Veillard652327a2003-09-29 18:02:38 +0000121#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000122static int copy = 0;
Daniel Veillard652327a2003-09-29 18:02:38 +0000123#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000124static int recovery = 0;
125static int noent = 0;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +0000126static int noblanks = 0;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000127static int noout = 0;
128static int nowrap = 0;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +0000129#ifdef LIBXML_OUTPUT_ENABLED
130static int format = 0;
131static const char *output = NULL;
132static int compress = 0;
133#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard4432df22003-09-28 18:58:27 +0000134#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000135static int valid = 0;
136static int postvalid = 0;
Daniel Veillardcd429612000-10-11 15:57:05 +0000137static char * dtdvalid = NULL;
Daniel Veillard66f68e72003-08-18 16:39:51 +0000138static char * dtdvalidfpi = NULL;
Daniel Veillard4432df22003-09-28 18:58:27 +0000139#endif
Daniel Veillard71531f32003-02-05 13:19:53 +0000140#ifdef LIBXML_SCHEMAS_ENABLED
141static char * relaxng = NULL;
142static xmlRelaxNGPtr relaxngschemas = NULL;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +0000143static char * schema = NULL;
144static xmlSchemaPtr wxschemas = NULL;
Daniel Veillard71531f32003-02-05 13:19:53 +0000145#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000146static int repeat = 0;
147static int insert = 0;
Daniel Veillard656ce942004-04-30 23:11:45 +0000148#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000149static int html = 0;
Daniel Veillard42fd4122003-11-04 08:47:48 +0000150static int xmlout = 0;
Daniel Veillard4432df22003-09-28 18:58:27 +0000151#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000152static int htmlout = 0;
Daniel Veillard73b013f2003-09-30 12:36:01 +0000153#ifdef LIBXML_PUSH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000154static int push = 0;
Daniel Veillard73b013f2003-09-30 12:36:01 +0000155#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillard46e370e2000-07-21 20:32:03 +0000156#ifdef HAVE_SYS_MMAN_H
157static int memory = 0;
158#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +0000159static int testIO = 0;
Daniel Veillardbe803962000-06-28 23:40:59 +0000160static char *encoding = NULL;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000161#ifdef LIBXML_XINCLUDE_ENABLED
162static int xinclude = 0;
163#endif
Daniel Veillard48da9102001-08-07 01:10:10 +0000164static int dtdattrs = 0;
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000165static int loaddtd = 0;
William M. Brack8304d872004-06-08 13:29:32 +0000166static xmllintReturnCode progresult = XMLLINT_RETURN_OK;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000167static int timing = 0;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000168static int generate = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000169static int dropdtd = 0;
Daniel Veillarde2940dd2001-08-22 00:06:49 +0000170#ifdef LIBXML_CATALOG_ENABLED
171static int catalogs = 0;
172static int nocatalogs = 0;
173#endif
Daniel Veillard25048d82004-08-14 22:37:54 +0000174#ifdef LIBXML_C14N_ENABLED
175static int canonical = 0;
176#endif
Daniel Veillard81273902003-09-30 00:43:48 +0000177#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +0000178static int stream = 0;
Daniel Veillard7899c5c2003-11-03 12:31:38 +0000179static int walker = 0;
Daniel Veillard81273902003-09-30 00:43:48 +0000180#endif /* LIBXML_READER_ENABLED */
Daniel Veillard8a1b1852003-01-05 22:37:17 +0000181static int chkregister = 0;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +0000182static int nbregister = 0;
Daniel Veillard81273902003-09-30 00:43:48 +0000183#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +0000184static int sax1 = 0;
Daniel Veillard81273902003-09-30 00:43:48 +0000185#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillardb3de70c2003-12-02 22:32:15 +0000186#ifdef LIBXML_PATTERN_ENABLED
187static const char *pattern = NULL;
188static xmlPatternPtr patternc = NULL;
189#endif
Daniel Veillard16fa96c2003-09-23 21:50:54 +0000190static int options = 0;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +0000191
Daniel Veillard87076042004-05-03 22:54:49 +0000192/************************************************************************
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000193 * *
194 * Entity loading control and customization. *
195 * *
196 ************************************************************************/
197#define MAX_PATHS 64
198static xmlChar *paths[MAX_PATHS + 1];
199static int nbpaths = 0;
200static int load_trace = 0;
201
202static
203void parsePath(const xmlChar *path) {
204 const xmlChar *cur;
205
206 if (path == NULL)
207 return;
208 while (*path != 0) {
209 if (nbpaths >= MAX_PATHS) {
210 fprintf(stderr, "MAX_PATHS reached: too many paths\n");
211 return;
212 }
213 cur = path;
214 while ((*cur == ' ') || (*cur == ':'))
215 cur++;
216 path = cur;
217 while ((*cur != 0) && (*cur != ' ') && (*cur != ':'))
218 cur++;
219 if (cur != path) {
220 paths[nbpaths] = xmlStrndup(path, cur - path);
221 if (paths[nbpaths] != NULL)
222 nbpaths++;
223 path = cur;
224 }
225 }
226}
227
228xmlExternalEntityLoader defaultEntityLoader = NULL;
229
230static xmlParserInputPtr
231xmllintExternalEntityLoader(const char *URL, const char *ID,
232 xmlParserCtxtPtr ctxt) {
233 xmlParserInputPtr ret;
234 warningSAXFunc warning = NULL;
235
236 int i;
237 const char *lastsegment = URL;
238 const char *iter = URL;
239
240 if (nbpaths > 0) {
241 while (*iter != 0) {
242 if (*iter == '/')
243 lastsegment = iter + 1;
244 iter++;
245 }
246 }
247
248 if ((ctxt != NULL) && (ctxt->sax != NULL)) {
249 warning = ctxt->sax->warning;
250 ctxt->sax->warning = NULL;
251 }
252
253 if (defaultEntityLoader != NULL) {
254 ret = defaultEntityLoader(URL, ID, ctxt);
255 if (ret != NULL) {
256 if (warning != NULL)
257 ctxt->sax->warning = warning;
258 if (load_trace) {
259 fprintf \
260 (stderr,
261 "Loaded URL=\"%s\" ID=\"%s\"\n",
262 URL ? URL : "(null)",
263 ID ? ID : "(null)");
264 }
265 return(ret);
266 }
267 }
268 for (i = 0;i < nbpaths;i++) {
269 xmlChar *newURL;
270
271 newURL = xmlStrdup((const xmlChar *) paths[i]);
272 newURL = xmlStrcat(newURL, (const xmlChar *) "/");
273 newURL = xmlStrcat(newURL, (const xmlChar *) lastsegment);
274 if (newURL != NULL) {
275 ret = defaultEntityLoader((const char *)newURL, ID, ctxt);
276 if (ret != NULL) {
277 if (warning != NULL)
278 ctxt->sax->warning = warning;
279 if (load_trace) {
280 fprintf \
281 (stderr,
282 "Loaded URL=\"%s\" ID=\"%s\"\n",
283 newURL,
284 ID ? ID : "(null)");
285 }
286 xmlFree(newURL);
287 return(ret);
288 }
289 xmlFree(newURL);
290 }
291 }
292 if (warning != NULL) {
293 ctxt->sax->warning = warning;
294 if (URL != NULL)
295 warning(ctxt, "failed to load external entity \"%s\"\n", URL);
296 else if (ID != NULL)
297 warning(ctxt, "failed to load external entity \"%s\"\n", ID);
298 }
299 return(NULL);
300}
301/************************************************************************
Daniel Veillard87076042004-05-03 22:54:49 +0000302 * *
303 * Memory allocation consumption debugging *
304 * *
305 ************************************************************************/
306
Daniel Veillard3af3b592004-05-05 19:22:30 +0000307static void
308OOM(void)
309{
Daniel Veillard87076042004-05-03 22:54:49 +0000310 fprintf(stderr, "Ran out of memory needs > %d bytes\n", maxmem);
William M. Brack8304d872004-06-08 13:29:32 +0000311 progresult = XMLLINT_ERR_MEM;
Daniel Veillard87076042004-05-03 22:54:49 +0000312}
313
Daniel Veillard3af3b592004-05-05 19:22:30 +0000314static void
315myFreeFunc(void *mem)
316{
Daniel Veillard87076042004-05-03 22:54:49 +0000317 xmlMemFree(mem);
318}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000319static void *
320myMallocFunc(size_t size)
321{
Daniel Veillard87076042004-05-03 22:54:49 +0000322 void *ret;
323
324 ret = xmlMemMalloc(size);
325 if (ret != NULL) {
326 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000327 OOM();
328 xmlMemFree(ret);
329 return (NULL);
330 }
Daniel Veillard87076042004-05-03 22:54:49 +0000331 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000332 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000333}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000334static void *
335myReallocFunc(void *mem, size_t size)
336{
Daniel Veillard87076042004-05-03 22:54:49 +0000337 void *ret;
338
339 ret = xmlMemRealloc(mem, size);
340 if (ret != NULL) {
341 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000342 OOM();
343 xmlMemFree(ret);
344 return (NULL);
345 }
Daniel Veillard87076042004-05-03 22:54:49 +0000346 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000347 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000348}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000349static char *
350myStrdupFunc(const char *str)
351{
Daniel Veillard87076042004-05-03 22:54:49 +0000352 char *ret;
353
354 ret = xmlMemoryStrdup(str);
355 if (ret != NULL) {
356 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000357 OOM();
358 xmlFree(ret);
359 return (NULL);
360 }
Daniel Veillard87076042004-05-03 22:54:49 +0000361 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000362 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000363}
Daniel Veillard87076042004-05-03 22:54:49 +0000364/************************************************************************
365 * *
366 * Internal timing routines to remove the necessity to have *
367 * unix-specific function calls. *
368 * *
369 ************************************************************************/
Daniel Veillard01db67c2001-12-18 07:09:59 +0000370
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000371#ifndef HAVE_GETTIMEOFDAY
372#ifdef HAVE_SYS_TIMEB_H
373#ifdef HAVE_SYS_TIME_H
374#ifdef HAVE_FTIME
375
Daniel Veillard01c13b52002-12-10 15:19:08 +0000376static int
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000377my_gettimeofday(struct timeval *tvp, void *tzp)
378{
379 struct timeb timebuffer;
380
381 ftime(&timebuffer);
382 if (tvp) {
383 tvp->tv_sec = timebuffer.time;
384 tvp->tv_usec = timebuffer.millitm * 1000L;
385 }
386 return (0);
387}
388#define HAVE_GETTIMEOFDAY 1
389#define gettimeofday my_gettimeofday
390
391#endif /* HAVE_FTIME */
392#endif /* HAVE_SYS_TIME_H */
393#endif /* HAVE_SYS_TIMEB_H */
394#endif /* !HAVE_GETTIMEOFDAY */
395
Daniel Veillard01db67c2001-12-18 07:09:59 +0000396#if defined(HAVE_GETTIMEOFDAY)
397static struct timeval begin, end;
398
399/*
400 * startTimer: call where you want to start timing
401 */
402static void
403startTimer(void)
404{
405 gettimeofday(&begin, NULL);
406}
407
408/*
409 * endTimer: call where you want to stop timing and to print out a
410 * message about the timing performed; format is a printf
411 * type argument
412 */
413static void
Daniel Veillard118aed72002-09-24 14:13:13 +0000414endTimer(const char *fmt, ...)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000415{
416 long msec;
417 va_list ap;
418
419 gettimeofday(&end, NULL);
420 msec = end.tv_sec - begin.tv_sec;
421 msec *= 1000;
422 msec += (end.tv_usec - begin.tv_usec) / 1000;
423
424#ifndef HAVE_STDARG_H
425#error "endTimer required stdarg functions"
426#endif
Daniel Veillard118aed72002-09-24 14:13:13 +0000427 va_start(ap, fmt);
428 vfprintf(stderr, fmt, ap);
Daniel Veillard01db67c2001-12-18 07:09:59 +0000429 va_end(ap);
430
431 fprintf(stderr, " took %ld ms\n", msec);
432}
433#elif defined(HAVE_TIME_H)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000434/*
435 * No gettimeofday function, so we have to make do with calling clock.
436 * This is obviously less accurate, but there's little we can do about
437 * that.
438 */
Daniel Veillard90bc3712002-03-07 15:12:58 +0000439#ifndef CLOCKS_PER_SEC
440#define CLOCKS_PER_SEC 100
441#endif
Daniel Veillard01db67c2001-12-18 07:09:59 +0000442
443static clock_t begin, end;
444static void
445startTimer(void)
446{
447 begin = clock();
448}
449static void
450endTimer(const char *fmt, ...)
451{
452 long msec;
453 va_list ap;
454
455 end = clock();
456 msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
457
458#ifndef HAVE_STDARG_H
459#error "endTimer required stdarg functions"
460#endif
461 va_start(ap, fmt);
462 vfprintf(stderr, fmt, ap);
463 va_end(ap);
464 fprintf(stderr, " took %ld ms\n", msec);
465}
466#else
467
468/*
469 * We don't have a gettimeofday or time.h, so we just don't do timing
470 */
471static void
472startTimer(void)
473{
474 /*
475 * Do nothing
476 */
477}
478static void
479endTimer(char *format, ...)
480{
481 /*
482 * We cannot do anything because we don't have a timing function
483 */
484#ifdef HAVE_STDARG_H
485 va_start(ap, format);
486 vfprintf(stderr, format, ap);
487 va_end(ap);
488 fprintf(stderr, " was not timed\n", msec);
489#else
490 /* We don't have gettimeofday, time or stdarg.h, what crazy world is
491 * this ?!
492 */
493#endif
494}
495#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000496/************************************************************************
497 * *
498 * HTML ouput *
499 * *
500 ************************************************************************/
501char buffer[50000];
502
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000503static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000504xmlHTMLEncodeSend(void) {
505 char *result;
506
507 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
508 if (result) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000509 xmlGenericError(xmlGenericErrorContext, "%s", result);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000510 xmlFree(result);
511 }
512 buffer[0] = 0;
513}
514
515/**
516 * xmlHTMLPrintFileInfo:
517 * @input: an xmlParserInputPtr input
518 *
519 * Displays the associated file and line informations for the current input
520 */
521
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000522static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000523xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000524 int len;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000525 xmlGenericError(xmlGenericErrorContext, "<p>");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000526
527 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000528 if (input != NULL) {
529 if (input->filename) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000530 snprintf(&buffer[len], sizeof(buffer) - len, "%s:%d: ", input->filename,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000531 input->line);
532 } else {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000533 snprintf(&buffer[len], sizeof(buffer) - len, "Entity: line %d: ", input->line);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000534 }
535 }
536 xmlHTMLEncodeSend();
537}
538
539/**
540 * xmlHTMLPrintFileContext:
541 * @input: an xmlParserInputPtr input
542 *
543 * Displays current context within the input content for error tracking
544 */
545
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000546static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000547xmlHTMLPrintFileContext(xmlParserInputPtr input) {
548 const xmlChar *cur, *base;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000549 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000550 int n;
551
552 if (input == NULL) return;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000553 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000554 cur = input->cur;
555 base = input->base;
556 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
557 cur--;
558 }
559 n = 0;
560 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
561 cur--;
562 if ((*cur == '\n') || (*cur == '\r')) cur++;
563 base = cur;
564 n = 0;
565 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000566 len = strlen(buffer);
567 snprintf(&buffer[len], sizeof(buffer) - len, "%c",
568 (unsigned char) *cur++);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000569 n++;
570 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000571 len = strlen(buffer);
572 snprintf(&buffer[len], sizeof(buffer) - len, "\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000573 cur = input->cur;
574 while ((*cur == '\n') || (*cur == '\r'))
575 cur--;
576 n = 0;
577 while ((cur != base) && (n++ < 80)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000578 len = strlen(buffer);
579 snprintf(&buffer[len], sizeof(buffer) - len, " ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000580 base++;
581 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000582 len = strlen(buffer);
583 snprintf(&buffer[len], sizeof(buffer) - len, "^\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000584 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000585 xmlGenericError(xmlGenericErrorContext, "</pre>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000586}
587
588/**
589 * xmlHTMLError:
590 * @ctx: an XML parser context
591 * @msg: the message to display/transmit
592 * @...: extra parameters for the message display
593 *
594 * Display and format an error messages, gives file, line, position and
595 * extra parameters.
596 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000597static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000598xmlHTMLError(void *ctx, const char *msg, ...)
599{
600 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
601 xmlParserInputPtr input;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000602 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000603 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000604
605 buffer[0] = 0;
606 input = ctxt->input;
607 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000608 input = ctxt->inputTab[ctxt->inputNr - 2];
609 }
610
611 xmlHTMLPrintFileInfo(input);
612
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000613 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000614 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000615 len = strlen(buffer);
616 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000617 va_end(args);
618 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000619 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000620
621 xmlHTMLPrintFileContext(input);
622 xmlHTMLEncodeSend();
623}
624
625/**
626 * xmlHTMLWarning:
627 * @ctx: an XML parser context
628 * @msg: the message to display/transmit
629 * @...: extra parameters for the message display
630 *
631 * Display and format a warning messages, gives file, line, position and
632 * extra parameters.
633 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000634static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000635xmlHTMLWarning(void *ctx, const char *msg, ...)
636{
637 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
638 xmlParserInputPtr input;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000639 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000640 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000641
642 buffer[0] = 0;
643 input = ctxt->input;
644 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000645 input = ctxt->inputTab[ctxt->inputNr - 2];
646 }
647
648
649 xmlHTMLPrintFileInfo(input);
650
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000651 xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000652 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000653 len = strlen(buffer);
654 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000655 va_end(args);
656 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000657 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000658
659 xmlHTMLPrintFileContext(input);
660 xmlHTMLEncodeSend();
661}
662
663/**
664 * xmlHTMLValidityError:
665 * @ctx: an XML parser context
666 * @msg: the message to display/transmit
667 * @...: extra parameters for the message display
668 *
669 * Display and format an validity error messages, gives file,
670 * line, position and extra parameters.
671 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000672static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000673xmlHTMLValidityError(void *ctx, const char *msg, ...)
674{
675 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
676 xmlParserInputPtr input;
677 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000678 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000679
680 buffer[0] = 0;
681 input = ctxt->input;
682 if ((input->filename == NULL) && (ctxt->inputNr > 1))
683 input = ctxt->inputTab[ctxt->inputNr - 2];
684
685 xmlHTMLPrintFileInfo(input);
686
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000687 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000688 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000689 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000690 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000691 va_end(args);
692 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000693 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000694
695 xmlHTMLPrintFileContext(input);
696 xmlHTMLEncodeSend();
697}
698
699/**
700 * xmlHTMLValidityWarning:
701 * @ctx: an XML parser context
702 * @msg: the message to display/transmit
703 * @...: extra parameters for the message display
704 *
705 * Display and format a validity warning messages, gives file, line,
706 * position and extra parameters.
707 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000708static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000709xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
710{
711 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
712 xmlParserInputPtr input;
713 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000714 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000715
716 buffer[0] = 0;
717 input = ctxt->input;
718 if ((input->filename == NULL) && (ctxt->inputNr > 1))
719 input = ctxt->inputTab[ctxt->inputNr - 2];
720
721 xmlHTMLPrintFileInfo(input);
722
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000723 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000724 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000725 len = strlen(buffer);
726 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000727 va_end(args);
728 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000729 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000730
731 xmlHTMLPrintFileContext(input);
732 xmlHTMLEncodeSend();
733}
734
735/************************************************************************
736 * *
737 * Shell Interface *
738 * *
739 ************************************************************************/
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000740#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000741#ifdef LIBXML_XPATH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000742/**
743 * xmlShellReadline:
744 * @prompt: the prompt value
745 *
746 * Read a string
747 *
748 * Returns a pointer to it or NULL on EOF the caller is expected to
749 * free the returned string.
750 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000751static char *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000752xmlShellReadline(char *prompt) {
753#ifdef HAVE_LIBREADLINE
754 char *line_read;
755
756 /* Get a line from the user. */
757 line_read = readline (prompt);
758
759 /* If the line has any text in it, save it on the history. */
760 if (line_read && *line_read)
761 add_history (line_read);
762
763 return (line_read);
764#else
765 char line_read[501];
Daniel Veillard29e43992001-12-13 22:21:58 +0000766 char *ret;
767 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000768
769 if (prompt != NULL)
770 fprintf(stdout, "%s", prompt);
771 if (!fgets(line_read, 500, stdin))
772 return(NULL);
773 line_read[500] = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000774 len = strlen(line_read);
775 ret = (char *) malloc(len + 1);
776 if (ret != NULL) {
777 memcpy (ret, line_read, len + 1);
778 }
779 return(ret);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000780#endif
781}
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000782#endif /* LIBXML_XPATH_ENABLED */
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000783#endif /* LIBXML_DEBUG_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000784
785/************************************************************************
786 * *
Daniel Veillard5e873c42000-04-12 13:27:38 +0000787 * I/O Interfaces *
788 * *
789 ************************************************************************/
790
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000791static int myRead(FILE *f, char * buf, int len) {
792 return(fread(buf, 1, len, f));
Daniel Veillard5e873c42000-04-12 13:27:38 +0000793}
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000794static void myClose(FILE *f) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000795 if (f != stdin) {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000796 fclose(f);
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000797 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000798}
799
Daniel Veillard81273902003-09-30 00:43:48 +0000800#ifdef LIBXML_READER_ENABLED
Daniel Veillard5e873c42000-04-12 13:27:38 +0000801/************************************************************************
802 * *
Daniel Veillard7704fb12003-01-03 16:19:51 +0000803 * Stream Test processing *
804 * *
805 ************************************************************************/
Daniel Veillard7704fb12003-01-03 16:19:51 +0000806static void processNode(xmlTextReaderPtr reader) {
Daniel Veillard198c1bf2003-10-20 17:07:41 +0000807 const xmlChar *name, *value;
Daniel Veillard7704fb12003-01-03 16:19:51 +0000808
Daniel Veillard198c1bf2003-10-20 17:07:41 +0000809 name = xmlTextReaderConstName(reader);
Daniel Veillarde59494f2003-01-04 16:35:29 +0000810 if (name == NULL)
Daniel Veillard7899c5c2003-11-03 12:31:38 +0000811 name = BAD_CAST "--";
Daniel Veillard99737f52003-03-22 14:55:50 +0000812
Daniel Veillard198c1bf2003-10-20 17:07:41 +0000813 value = xmlTextReaderConstValue(reader);
Daniel Veillard7704fb12003-01-03 16:19:51 +0000814
Daniel Veillard99737f52003-03-22 14:55:50 +0000815 printf("%d %d %s %d %d",
Daniel Veillarde59494f2003-01-04 16:35:29 +0000816 xmlTextReaderDepth(reader),
817 xmlTextReaderNodeType(reader),
818 name,
Daniel Veillard99737f52003-03-22 14:55:50 +0000819 xmlTextReaderIsEmptyElement(reader),
820 xmlTextReaderHasValue(reader));
Daniel Veillarde59494f2003-01-04 16:35:29 +0000821 if (value == NULL)
822 printf("\n");
823 else {
824 printf(" %s\n", value);
Daniel Veillard7704fb12003-01-03 16:19:51 +0000825 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +0000826#ifdef LIBXML_PATTERN_ENABLED
827 if (patternc) {
828 if (xmlPatternMatch(patternc, xmlTextReaderCurrentNode(reader)) == 1) {
829 printf("Node matches pattern %s\n", pattern);
830 }
831 }
832#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +0000833}
834
835static void streamFile(char *filename) {
836 xmlTextReaderPtr reader;
837 int ret;
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +0000838#ifdef HAVE_SYS_MMAN_H
839 int fd = -1;
840 struct stat info;
841 const char *base = NULL;
842 xmlParserInputBufferPtr input = NULL;
Daniel Veillard7704fb12003-01-03 16:19:51 +0000843
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +0000844 if (memory) {
845 if (stat(filename, &info) < 0)
846 return;
847 if ((fd = open(filename, O_RDONLY)) < 0)
848 return;
849 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
850 if (base == (void *) MAP_FAILED)
851 return;
852
Daniel Veillard7899c5c2003-11-03 12:31:38 +0000853 reader = xmlReaderForMemory(base, info.st_size, filename,
854 NULL, options);
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +0000855 } else
856#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +0000857 reader = xmlReaderForFile(filename, NULL, options);
858
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +0000859
Daniel Veillard7704fb12003-01-03 16:19:51 +0000860 if (reader != NULL) {
Daniel Veillard4432df22003-09-28 18:58:27 +0000861#ifdef LIBXML_VALID_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +0000862 if (valid)
863 xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
Daniel Veillardce192eb2003-04-16 15:58:05 +0000864 else
Daniel Veillard4432df22003-09-28 18:58:27 +0000865#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardce192eb2003-04-16 15:58:05 +0000866 xmlTextReaderSetParserProp(reader, XML_PARSER_LOADDTD, 1);
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000867#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +0000868 if (relaxng != NULL) {
Daniel Veillard81514ba2003-09-16 23:17:26 +0000869 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +0000870 startTimer();
871 }
872 ret = xmlTextReaderRelaxNGValidate(reader, relaxng);
873 if (ret < 0) {
874 xmlGenericError(xmlGenericErrorContext,
875 "Relax-NG schema %s failed to compile\n", relaxng);
William M. Brack8304d872004-06-08 13:29:32 +0000876 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillardce192eb2003-04-16 15:58:05 +0000877 relaxng = NULL;
878 }
Daniel Veillard81514ba2003-09-16 23:17:26 +0000879 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +0000880 endTimer("Compiling the schemas");
881 }
882 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000883#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +0000884
885 /*
886 * Process all nodes in sequence
887 */
Daniel Veillard81514ba2003-09-16 23:17:26 +0000888 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +0000889 startTimer();
890 }
Daniel Veillard7704fb12003-01-03 16:19:51 +0000891 ret = xmlTextReaderRead(reader);
892 while (ret == 1) {
Daniel Veillardb3de70c2003-12-02 22:32:15 +0000893 if ((debug)
894#ifdef LIBXML_PATTERN_ENABLED
895 || (patternc)
896#endif
897 )
Daniel Veillard7704fb12003-01-03 16:19:51 +0000898 processNode(reader);
899 ret = xmlTextReaderRead(reader);
900 }
Daniel Veillard81514ba2003-09-16 23:17:26 +0000901 if ((timing) && (!repeat)) {
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000902#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf54cd532004-02-25 11:52:31 +0000903 if (relaxng != NULL)
Daniel Veillard49138f12004-02-19 12:58:36 +0000904 endTimer("Parsing and validating");
905 else
Daniel Veillardf54cd532004-02-25 11:52:31 +0000906#endif
Daniel Veillard4432df22003-09-28 18:58:27 +0000907#ifdef LIBXML_VALID_ENABLED
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000908 if (valid)
Daniel Veillardce192eb2003-04-16 15:58:05 +0000909 endTimer("Parsing and validating");
910 else
Daniel Veillard4432df22003-09-28 18:58:27 +0000911#endif
Daniel Veillardf54cd532004-02-25 11:52:31 +0000912 endTimer("Parsing");
Daniel Veillardce192eb2003-04-16 15:58:05 +0000913 }
Daniel Veillard7704fb12003-01-03 16:19:51 +0000914
Daniel Veillard4432df22003-09-28 18:58:27 +0000915#ifdef LIBXML_VALID_ENABLED
Daniel Veillardf6bad792003-04-11 19:38:54 +0000916 if (valid) {
917 if (xmlTextReaderIsValid(reader) != 1) {
918 xmlGenericError(xmlGenericErrorContext,
919 "Document %s does not validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +0000920 progresult = XMLLINT_ERR_VALID;
Daniel Veillardf6bad792003-04-11 19:38:54 +0000921 }
922 }
Daniel Veillard4432df22003-09-28 18:58:27 +0000923#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000924#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf4e55762003-04-15 23:32:22 +0000925 if (relaxng != NULL) {
926 if (xmlTextReaderIsValid(reader) != 1) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +0000927 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +0000928 progresult = XMLLINT_ERR_VALID;
Daniel Veillardf4e55762003-04-15 23:32:22 +0000929 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +0000930 fprintf(stderr, "%s validates\n", filename);
Daniel Veillardf4e55762003-04-15 23:32:22 +0000931 }
932 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000933#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +0000934 /*
935 * Done, cleanup and status
936 */
937 xmlFreeTextReader(reader);
938 if (ret != 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +0000939 fprintf(stderr, "%s : failed to parse\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +0000940 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7704fb12003-01-03 16:19:51 +0000941 }
942 } else {
943 fprintf(stderr, "Unable to open %s\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +0000944 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7704fb12003-01-03 16:19:51 +0000945 }
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +0000946#ifdef HAVE_SYS_MMAN_H
947 if (memory) {
948 xmlFreeParserInputBuffer(input);
949 munmap((char *) base, info.st_size);
950 close(fd);
951 }
952#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +0000953}
Daniel Veillard7899c5c2003-11-03 12:31:38 +0000954
955static void walkDoc(xmlDocPtr doc) {
956 xmlTextReaderPtr reader;
957 int ret;
958
959 reader = xmlReaderWalker(doc);
960 if (reader != NULL) {
961 if ((timing) && (!repeat)) {
962 startTimer();
963 }
964 ret = xmlTextReaderRead(reader);
965 while (ret == 1) {
Daniel Veillardb3de70c2003-12-02 22:32:15 +0000966 if ((debug)
967#ifdef LIBXML_PATTERN_ENABLED
968 || (patternc)
969#endif
970 )
Daniel Veillard7899c5c2003-11-03 12:31:38 +0000971 processNode(reader);
972 ret = xmlTextReaderRead(reader);
973 }
974 if ((timing) && (!repeat)) {
975 endTimer("walking through the doc");
976 }
977 xmlFreeTextReader(reader);
978 if (ret != 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +0000979 fprintf(stderr, "failed to walk through the doc\n");
William M. Brack8304d872004-06-08 13:29:32 +0000980 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7899c5c2003-11-03 12:31:38 +0000981 }
982 } else {
983 fprintf(stderr, "Failed to crate a reader from the document\n");
William M. Brack8304d872004-06-08 13:29:32 +0000984 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7899c5c2003-11-03 12:31:38 +0000985 }
986}
Daniel Veillard81273902003-09-30 00:43:48 +0000987#endif /* LIBXML_READER_ENABLED */
Daniel Veillard7704fb12003-01-03 16:19:51 +0000988
989/************************************************************************
990 * *
991 * Tree Test processing *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000992 * *
993 ************************************************************************/
Daniel Veillarde96a2a42003-09-24 21:23:56 +0000994static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
Daniel Veillard652327a2003-09-29 18:02:38 +0000995 xmlDocPtr doc = NULL;
996#ifdef LIBXML_TREE_ENABLED
997 xmlDocPtr tmp;
998#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000999
Daniel Veillard48b2f892001-02-25 16:11:03 +00001000 if ((timing) && (!repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00001001 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001002
1003
Daniel Veillard652327a2003-09-29 18:02:38 +00001004#ifdef LIBXML_TREE_ENABLED
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001005 if (filename == NULL) {
1006 if (generate) {
1007 xmlNodePtr n;
1008
1009 doc = xmlNewDoc(BAD_CAST "1.0");
Daniel Veillard95ddcd32004-10-26 21:53:55 +00001010 n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001011 xmlNodeSetContent(n, BAD_CAST "abc");
1012 xmlDocSetRootElement(doc, n);
1013 }
1014 }
Daniel Veillard652327a2003-09-29 18:02:38 +00001015#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001016#ifdef LIBXML_HTML_ENABLED
Daniel Veillard73b013f2003-09-30 12:36:01 +00001017#ifdef LIBXML_PUSH_ENABLED
William M. Brack78637da2003-07-31 14:47:38 +00001018 else if ((html) && (push)) {
1019 FILE *f;
1020
William M. Brack3403add2004-06-27 02:07:51 +00001021#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
1022 f = fopen(filename, "rb");
1023#else
1024 f = fopen(filename, "r");
1025#endif
William M. Brack78637da2003-07-31 14:47:38 +00001026 if (f != NULL) {
1027 int res, size = 3;
1028 char chars[4096];
1029 htmlParserCtxtPtr ctxt;
1030
1031 /* if (repeat) */
1032 size = 4096;
1033 res = fread(chars, 1, 4, f);
1034 if (res > 0) {
1035 ctxt = htmlCreatePushParserCtxt(NULL, NULL,
William M. Brack1d75c8a2003-10-27 13:48:16 +00001036 chars, res, filename, XML_CHAR_ENCODING_NONE);
William M. Brack78637da2003-07-31 14:47:38 +00001037 while ((res = fread(chars, 1, size, f)) > 0) {
1038 htmlParseChunk(ctxt, chars, res, 0);
1039 }
1040 htmlParseChunk(ctxt, chars, 0, 1);
1041 doc = ctxt->myDoc;
1042 htmlFreeParserCtxt(ctxt);
1043 }
1044 fclose(f);
1045 }
1046 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00001047#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001048 else if (html) {
Daniel Veillard9475a352003-09-26 12:47:50 +00001049 doc = htmlReadFile(filename, NULL, options);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001050 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001051#endif /* LIBXML_HTML_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001052 else {
Daniel Veillard73b013f2003-09-30 12:36:01 +00001053#ifdef LIBXML_PUSH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001054 /*
1055 * build an XML tree from a string;
1056 */
1057 if (push) {
1058 FILE *f;
1059
Daniel Veillard4a6845d2001-01-03 13:32:39 +00001060 /* '-' Usually means stdin -<sven@zen.org> */
1061 if ((filename[0] == '-') && (filename[1] == 0)) {
1062 f = stdin;
1063 } else {
William M. Brack3403add2004-06-27 02:07:51 +00001064#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
1065 f = fopen(filename, "rb");
1066#else
1067 f = fopen(filename, "r");
1068#endif
Daniel Veillard4a6845d2001-01-03 13:32:39 +00001069 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001070 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +00001071 int ret;
Daniel Veillarda880b122003-04-21 21:36:41 +00001072 int res, size = 1024;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001073 char chars[1024];
1074 xmlParserCtxtPtr ctxt;
1075
Daniel Veillarda880b122003-04-21 21:36:41 +00001076 /* if (repeat) size = 1024; */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001077 res = fread(chars, 1, 4, f);
1078 if (res > 0) {
1079 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
1080 chars, res, filename);
Daniel Veillard500a1de2004-03-22 15:22:58 +00001081 xmlCtxtUseOptions(ctxt, options);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001082 while ((res = fread(chars, 1, size, f)) > 0) {
1083 xmlParseChunk(ctxt, chars, res, 0);
1084 }
1085 xmlParseChunk(ctxt, chars, 0, 1);
1086 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +00001087 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001088 xmlFreeParserCtxt(ctxt);
Daniel Veillarde715dd22000-08-29 18:29:38 +00001089 if (!ret) {
1090 xmlFreeDoc(doc);
1091 doc = NULL;
1092 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001093 }
1094 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00001095 } else
1096#endif /* LIBXML_PUSH_ENABLED */
1097 if (testIO) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +00001098 if ((filename[0] == '-') && (filename[1] == 0)) {
Daniel Veillard60942de2003-09-25 21:05:58 +00001099 doc = xmlReadFd(0, NULL, NULL, options);
Daniel Veillard4a6845d2001-01-03 13:32:39 +00001100 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00001101 FILE *f;
Daniel Veillard5e873c42000-04-12 13:27:38 +00001102
William M. Brack3403add2004-06-27 02:07:51 +00001103#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
1104 f = fopen(filename, "rb");
1105#else
Daniel Veillard16fa96c2003-09-23 21:50:54 +00001106 f = fopen(filename, "r");
William M. Brack3403add2004-06-27 02:07:51 +00001107#endif
Daniel Veillarde96a2a42003-09-24 21:23:56 +00001108 if (f != NULL) {
1109 if (rectxt == NULL)
1110 doc = xmlReadIO((xmlInputReadCallback) myRead,
1111 (xmlInputCloseCallback) myClose, f,
Daniel Veillard60942de2003-09-25 21:05:58 +00001112 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00001113 else
1114 doc = xmlCtxtReadIO(rectxt,
1115 (xmlInputReadCallback) myRead,
1116 (xmlInputCloseCallback) myClose, f,
Daniel Veillard60942de2003-09-25 21:05:58 +00001117 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00001118 } else
Daniel Veillard5e873c42000-04-12 13:27:38 +00001119 doc = NULL;
Daniel Veillard5e873c42000-04-12 13:27:38 +00001120 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001121 } else if (htmlout) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001122 xmlParserCtxtPtr ctxt;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001123
Daniel Veillarde96a2a42003-09-24 21:23:56 +00001124 if (rectxt == NULL)
1125 ctxt = xmlNewParserCtxt();
1126 else
1127 ctxt = rectxt;
Daniel Veillard88a172f2000-08-04 18:23:10 +00001128 if (ctxt == NULL) {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00001129 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +00001130 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00001131 ctxt->sax->error = xmlHTMLError;
1132 ctxt->sax->warning = xmlHTMLWarning;
1133 ctxt->vctxt.error = xmlHTMLValidityError;
1134 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001135
Daniel Veillard16fa96c2003-09-23 21:50:54 +00001136 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001137
Daniel Veillarde96a2a42003-09-24 21:23:56 +00001138 if (rectxt == NULL)
1139 xmlFreeParserCtxt(ctxt);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001140 }
Daniel Veillard46e370e2000-07-21 20:32:03 +00001141#ifdef HAVE_SYS_MMAN_H
1142 } else if (memory) {
1143 int fd;
1144 struct stat info;
1145 const char *base;
1146 if (stat(filename, &info) < 0)
1147 return;
1148 if ((fd = open(filename, O_RDONLY)) < 0)
1149 return;
1150 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillard29579362000-08-14 17:57:48 +00001151 if (base == (void *) MAP_FAILED)
Daniel Veillard46e370e2000-07-21 20:32:03 +00001152 return;
1153
Daniel Veillarde96a2a42003-09-24 21:23:56 +00001154 if (rectxt == NULL)
Daniel Veillard60942de2003-09-25 21:05:58 +00001155 doc = xmlReadMemory((char *) base, info.st_size,
1156 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00001157 else
Daniel Veillard60942de2003-09-25 21:05:58 +00001158 doc = xmlCtxtReadMemory(rectxt, (char *) base, info.st_size,
1159 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00001160
Daniel Veillard46e370e2000-07-21 20:32:03 +00001161 munmap((char *) base, info.st_size);
1162#endif
Daniel Veillard4432df22003-09-28 18:58:27 +00001163#ifdef LIBXML_VALID_ENABLED
Daniel Veillardea7751d2002-12-20 00:16:24 +00001164 } else if (valid) {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00001165 xmlParserCtxtPtr ctxt = NULL;
Daniel Veillardea7751d2002-12-20 00:16:24 +00001166
Daniel Veillarde96a2a42003-09-24 21:23:56 +00001167 if (rectxt == NULL)
1168 ctxt = xmlNewParserCtxt();
1169 else
1170 ctxt = rectxt;
Daniel Veillardea7751d2002-12-20 00:16:24 +00001171 if (ctxt == NULL) {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00001172 doc = NULL;
Daniel Veillardea7751d2002-12-20 00:16:24 +00001173 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00001174 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
1175
1176 if (ctxt->valid == 0)
William M. Brack8304d872004-06-08 13:29:32 +00001177 progresult = XMLLINT_ERR_RDFILE;
Daniel Veillarde96a2a42003-09-24 21:23:56 +00001178 if (rectxt == NULL)
1179 xmlFreeParserCtxt(ctxt);
Daniel Veillardea7751d2002-12-20 00:16:24 +00001180 }
Daniel Veillard4432df22003-09-28 18:58:27 +00001181#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardea7751d2002-12-20 00:16:24 +00001182 } else {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00001183 if (rectxt != NULL)
1184 doc = xmlCtxtReadFile(rectxt, filename, NULL, options);
1185 else
1186 doc = xmlReadFile(filename, NULL, options);
Daniel Veillardea7751d2002-12-20 00:16:24 +00001187 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001188 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001189
Daniel Veillard88a172f2000-08-04 18:23:10 +00001190 /*
1191 * If we don't have a document we might as well give up. Do we
1192 * want an error message here? <sven@zen.org> */
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00001193 if (doc == NULL) {
William M. Brack8304d872004-06-08 13:29:32 +00001194 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard88a172f2000-08-04 18:23:10 +00001195 return;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00001196 }
1197
Daniel Veillard48b2f892001-02-25 16:11:03 +00001198 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001199 endTimer("Parsing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001200 }
1201
Daniel Veillard29e43992001-12-13 22:21:58 +00001202 /*
1203 * Remove DOCTYPE nodes
1204 */
1205 if (dropdtd) {
1206 xmlDtdPtr dtd;
1207
1208 dtd = xmlGetIntSubset(doc);
1209 if (dtd != NULL) {
1210 xmlUnlinkNode((xmlNodePtr)dtd);
1211 xmlFreeDtd(dtd);
1212 }
1213 }
1214
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00001215#ifdef LIBXML_XINCLUDE_ENABLED
Daniel Veillard48b2f892001-02-25 16:11:03 +00001216 if (xinclude) {
1217 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001218 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001219 }
Daniel Veillarde74d2e12003-12-09 11:35:37 +00001220 xmlXIncludeProcessFlags(doc, options);
Daniel Veillard48b2f892001-02-25 16:11:03 +00001221 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001222 endTimer("Xinclude processing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001223 }
1224 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00001225#endif
Daniel Veillard88a172f2000-08-04 18:23:10 +00001226
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001227#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00001228#ifdef LIBXML_XPATH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001229 /*
Daniel Veillardcbaf3992001-12-31 16:16:02 +00001230 * shell interaction
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001231 */
1232 if (shell)
1233 xmlShell(doc, filename, xmlShellReadline, stdout);
1234#endif
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00001235#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001236
Daniel Veillard652327a2003-09-29 18:02:38 +00001237#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001238 /*
1239 * test intermediate copy if needed.
1240 */
1241 if (copy) {
1242 tmp = doc;
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00001243 if (timing) {
1244 startTimer();
1245 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001246 doc = xmlCopyDoc(doc, 1);
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00001247 if (timing) {
1248 endTimer("Copying");
1249 }
1250 if (timing) {
1251 startTimer();
1252 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001253 xmlFreeDoc(tmp);
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00001254 if (timing) {
1255 endTimer("Freeing original");
1256 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001257 }
Daniel Veillard652327a2003-09-29 18:02:38 +00001258#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001259
Daniel Veillard4432df22003-09-28 18:58:27 +00001260#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001261 if ((insert) && (!html)) {
1262 const xmlChar* list[256];
1263 int nb, i;
1264 xmlNodePtr node;
1265
1266 if (doc->children != NULL) {
1267 node = doc->children;
1268 while ((node != NULL) && (node->last == NULL)) node = node->next;
1269 if (node != NULL) {
1270 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
1271 if (nb < 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001272 fprintf(stderr, "could not get valid list of elements\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001273 } else if (nb == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001274 fprintf(stderr, "No element can be inserted under root\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001275 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001276 fprintf(stderr, "%d element types can be inserted under root:\n",
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001277 nb);
1278 for (i = 0;i < nb;i++) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001279 fprintf(stderr, "%s\n", (char *) list[i]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001280 }
1281 }
1282 }
1283 }
Daniel Veillard4432df22003-09-28 18:58:27 +00001284 }else
1285#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001286#ifdef LIBXML_READER_ENABLED
1287 if (walker) {
1288 walkDoc(doc);
1289 }
1290#endif /* LIBXML_READER_ENABLED */
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00001291#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard4432df22003-09-28 18:58:27 +00001292 if (noout == 0) {
Daniel Veillard3df01182003-12-10 10:17:51 +00001293 int ret;
1294
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001295 /*
1296 * print it.
1297 */
1298#ifdef LIBXML_DEBUG_ENABLED
1299 if (!debug) {
1300#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00001301 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001302 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001303 }
Daniel Veillard656ce942004-04-30 23:11:45 +00001304#ifdef LIBXML_HTML_ENABLED
Daniel Veillard42fd4122003-11-04 08:47:48 +00001305 if ((html) && (!xmlout)) {
1306 if (compress) {
1307 htmlSaveFile(output ? output : "-", doc);
1308 }
1309 else if (encoding != NULL) {
1310 if ( format ) {
1311 htmlSaveFileFormat(output ? output : "-", doc, encoding, 1);
1312 }
1313 else {
1314 htmlSaveFileFormat(output ? output : "-", doc, encoding, 0);
1315 }
1316 }
1317 else if (format) {
1318 htmlSaveFileFormat(output ? output : "-", doc, NULL, 1);
1319 }
1320 else {
1321 FILE *out;
1322 if (output == NULL)
1323 out = stdout;
1324 else {
1325 out = fopen(output,"wb");
1326 }
1327 if (out != NULL) {
1328 if (htmlDocDump(out, doc) < 0)
William M. Brack8304d872004-06-08 13:29:32 +00001329 progresult = XMLLINT_ERR_OUT;
Daniel Veillard42fd4122003-11-04 08:47:48 +00001330
1331 if (output != NULL)
1332 fclose(out);
1333 } else {
1334 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00001335 progresult = XMLLINT_ERR_OUT;
Daniel Veillard42fd4122003-11-04 08:47:48 +00001336 }
1337 }
1338 if ((timing) && (!repeat)) {
1339 endTimer("Saving");
1340 }
1341 } else
1342#endif
Daniel Veillard25048d82004-08-14 22:37:54 +00001343#ifdef LIBXML_C14N_ENABLED
1344 if (canonical) {
1345 xmlChar *result = NULL;
1346 int size;
1347
1348 size = xmlC14NDocDumpMemory(doc, NULL, 0, NULL, 1, &result);
1349 if (size >= 0) {
1350 write(1, result, size);
1351 xmlFree(result);
1352 } else {
1353 fprintf(stderr, "Failed to canonicalize\n");
1354 progresult = XMLLINT_ERR_OUT;
1355 }
1356 } else
1357#endif
Daniel Veillard3b2c2612001-04-04 00:09:00 +00001358#ifdef HAVE_SYS_MMAN_H
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001359 if (memory) {
1360 xmlChar *result;
1361 int len;
1362
1363 if (encoding != NULL) {
Daniel Veillardd536f702001-11-08 17:32:47 +00001364 if ( format ) {
1365 xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
1366 } else {
1367 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
1368 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001369 } else {
Daniel Veillard90493a92001-08-14 14:12:47 +00001370 if (format)
1371 xmlDocDumpFormatMemory(doc, &result, &len, 1);
1372 else
1373 xmlDocDumpMemory(doc, &result, &len);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001374 }
1375 if (result == NULL) {
1376 fprintf(stderr, "Failed to save\n");
Daniel Veillard25048d82004-08-14 22:37:54 +00001377 progresult = XMLLINT_ERR_OUT;
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001378 } else {
1379 write(1, result, len);
1380 xmlFree(result);
1381 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +00001382 } else
1383#endif /* HAVE_SYS_MMAN_H */
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001384 if (compress) {
1385 xmlSaveFile(output ? output : "-", doc);
1386 }
Daniel Veillardd536f702001-11-08 17:32:47 +00001387 else if (encoding != NULL) {
1388 if ( format ) {
Daniel Veillard3df01182003-12-10 10:17:51 +00001389 ret = xmlSaveFormatFileEnc(output ? output : "-", doc,
1390 encoding, 1);
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001391 }
Daniel Veillardd536f702001-11-08 17:32:47 +00001392 else {
Daniel Veillard3df01182003-12-10 10:17:51 +00001393 ret = xmlSaveFileEnc(output ? output : "-", doc, encoding);
1394 }
1395 if (ret < 0) {
1396 fprintf(stderr, "failed save to %s\n",
1397 output ? output : "-");
William M. Brack8304d872004-06-08 13:29:32 +00001398 progresult = XMLLINT_ERR_OUT;
Daniel Veillardd536f702001-11-08 17:32:47 +00001399 }
1400 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001401 else if (format) {
Daniel Veillard3df01182003-12-10 10:17:51 +00001402 ret = xmlSaveFormatFile(output ? output : "-", doc, 1);
1403 if (ret < 0) {
1404 fprintf(stderr, "failed save to %s\n",
1405 output ? output : "-");
William M. Brack8304d872004-06-08 13:29:32 +00001406 progresult = XMLLINT_ERR_OUT;
Daniel Veillard3df01182003-12-10 10:17:51 +00001407 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001408 }
1409 else {
1410 FILE *out;
1411 if (output == NULL)
1412 out = stdout;
1413 else {
1414 out = fopen(output,"wb");
1415 }
Daniel Veillard05d987b2003-10-08 11:54:57 +00001416 if (out != NULL) {
Daniel Veillard828ce832003-10-08 19:19:10 +00001417 if (xmlDocDump(out, doc) < 0)
William M. Brack8304d872004-06-08 13:29:32 +00001418 progresult = XMLLINT_ERR_OUT;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001419
Daniel Veillard05d987b2003-10-08 11:54:57 +00001420 if (output != NULL)
1421 fclose(out);
1422 } else {
1423 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00001424 progresult = XMLLINT_ERR_OUT;
Daniel Veillard05d987b2003-10-08 11:54:57 +00001425 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001426 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001427 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001428 endTimer("Saving");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001429 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001430#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001431 } else {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001432 FILE *out;
1433 if (output == NULL)
1434 out = stdout;
1435 else {
1436 out = fopen(output,"wb");
1437 }
Daniel Veillard05d987b2003-10-08 11:54:57 +00001438 if (out != NULL) {
1439 xmlDebugDumpDocument(out, doc);
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001440
Daniel Veillard05d987b2003-10-08 11:54:57 +00001441 if (output != NULL)
1442 fclose(out);
1443 } else {
1444 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00001445 progresult = XMLLINT_ERR_OUT;
Daniel Veillard05d987b2003-10-08 11:54:57 +00001446 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001447 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001448#endif
1449 }
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00001450#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001451
Daniel Veillard4432df22003-09-28 18:58:27 +00001452#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001453 /*
1454 * A posteriori validation test
1455 */
Daniel Veillard66f68e72003-08-18 16:39:51 +00001456 if ((dtdvalid != NULL) || (dtdvalidfpi != NULL)) {
Daniel Veillardcd429612000-10-11 15:57:05 +00001457 xmlDtdPtr dtd;
1458
Daniel Veillard48b2f892001-02-25 16:11:03 +00001459 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001460 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001461 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00001462 if (dtdvalid != NULL)
1463 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
1464 else
1465 dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL);
Daniel Veillard48b2f892001-02-25 16:11:03 +00001466 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001467 endTimer("Parsing DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001468 }
Daniel Veillardcd429612000-10-11 15:57:05 +00001469 if (dtd == NULL) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00001470 if (dtdvalid != NULL)
1471 xmlGenericError(xmlGenericErrorContext,
1472 "Could not parse DTD %s\n", dtdvalid);
1473 else
1474 xmlGenericError(xmlGenericErrorContext,
1475 "Could not parse DTD %s\n", dtdvalidfpi);
William M. Brack8304d872004-06-08 13:29:32 +00001476 progresult = XMLLINT_ERR_DTD;
Daniel Veillardcd429612000-10-11 15:57:05 +00001477 } else {
Daniel Veillarda37aab82003-06-09 09:10:36 +00001478 xmlValidCtxtPtr cvp;
1479
1480 if ((cvp = xmlNewValidCtxt()) == NULL) {
1481 xmlGenericError(xmlGenericErrorContext,
1482 "Couldn't allocate validation context\n");
1483 exit(-1);
1484 }
1485 cvp->userData = (void *) stderr;
1486 cvp->error = (xmlValidityErrorFunc) fprintf;
1487 cvp->warning = (xmlValidityWarningFunc) fprintf;
1488
Daniel Veillard48b2f892001-02-25 16:11:03 +00001489 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001490 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001491 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00001492 if (!xmlValidateDtd(cvp, doc, dtd)) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00001493 if (dtdvalid != NULL)
1494 xmlGenericError(xmlGenericErrorContext,
1495 "Document %s does not validate against %s\n",
1496 filename, dtdvalid);
1497 else
1498 xmlGenericError(xmlGenericErrorContext,
1499 "Document %s does not validate against %s\n",
1500 filename, dtdvalidfpi);
William M. Brack8304d872004-06-08 13:29:32 +00001501 progresult = XMLLINT_ERR_VALID;
Daniel Veillardcd429612000-10-11 15:57:05 +00001502 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001503 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001504 endTimer("Validating against DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001505 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00001506 xmlFreeValidCtxt(cvp);
Daniel Veillardcd429612000-10-11 15:57:05 +00001507 xmlFreeDtd(dtd);
1508 }
1509 } else if (postvalid) {
Daniel Veillarda37aab82003-06-09 09:10:36 +00001510 xmlValidCtxtPtr cvp;
1511
1512 if ((cvp = xmlNewValidCtxt()) == NULL) {
1513 xmlGenericError(xmlGenericErrorContext,
1514 "Couldn't allocate validation context\n");
1515 exit(-1);
1516 }
1517
Daniel Veillard48b2f892001-02-25 16:11:03 +00001518 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001519 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001520 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00001521 cvp->userData = (void *) stderr;
1522 cvp->error = (xmlValidityErrorFunc) fprintf;
1523 cvp->warning = (xmlValidityWarningFunc) fprintf;
1524 if (!xmlValidateDocument(cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001525 xmlGenericError(xmlGenericErrorContext,
1526 "Document %s does not validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001527 progresult = XMLLINT_ERR_VALID;
Daniel Veillardcd429612000-10-11 15:57:05 +00001528 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001529 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001530 endTimer("Validating");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001531 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00001532 xmlFreeValidCtxt(cvp);
Daniel Veillard4432df22003-09-28 18:58:27 +00001533 }
1534#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard71531f32003-02-05 13:19:53 +00001535#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard4432df22003-09-28 18:58:27 +00001536 if (relaxngschemas != NULL) {
Daniel Veillard71531f32003-02-05 13:19:53 +00001537 xmlRelaxNGValidCtxtPtr ctxt;
1538 int ret;
1539
Daniel Veillard42f12e92003-03-07 18:32:59 +00001540 if ((timing) && (!repeat)) {
1541 startTimer();
1542 }
1543
Daniel Veillard71531f32003-02-05 13:19:53 +00001544 ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
1545 xmlRelaxNGSetValidErrors(ctxt,
1546 (xmlRelaxNGValidityErrorFunc) fprintf,
1547 (xmlRelaxNGValidityWarningFunc) fprintf,
1548 stderr);
1549 ret = xmlRelaxNGValidateDoc(ctxt, doc);
1550 if (ret == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001551 fprintf(stderr, "%s validates\n", filename);
Daniel Veillard71531f32003-02-05 13:19:53 +00001552 } else if (ret > 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001553 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001554 progresult = XMLLINT_ERR_VALID;
Daniel Veillard71531f32003-02-05 13:19:53 +00001555 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001556 fprintf(stderr, "%s validation generated an internal error\n",
Daniel Veillard71531f32003-02-05 13:19:53 +00001557 filename);
William M. Brack8304d872004-06-08 13:29:32 +00001558 progresult = XMLLINT_ERR_VALID;
Daniel Veillard71531f32003-02-05 13:19:53 +00001559 }
1560 xmlRelaxNGFreeValidCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00001561 if ((timing) && (!repeat)) {
1562 endTimer("Validating");
1563 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001564 } else if (wxschemas != NULL) {
1565 xmlSchemaValidCtxtPtr ctxt;
1566 int ret;
1567
1568 if ((timing) && (!repeat)) {
1569 startTimer();
1570 }
1571
1572 ctxt = xmlSchemaNewValidCtxt(wxschemas);
1573 xmlSchemaSetValidErrors(ctxt,
1574 (xmlSchemaValidityErrorFunc) fprintf,
1575 (xmlSchemaValidityWarningFunc) fprintf,
1576 stderr);
1577 ret = xmlSchemaValidateDoc(ctxt, doc);
1578 if (ret == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001579 fprintf(stderr, "%s validates\n", filename);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001580 } else if (ret > 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001581 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001582 progresult = XMLLINT_ERR_VALID;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001583 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001584 fprintf(stderr, "%s validation generated an internal error\n",
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001585 filename);
William M. Brack8304d872004-06-08 13:29:32 +00001586 progresult = XMLLINT_ERR_VALID;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001587 }
1588 xmlSchemaFreeValidCtxt(ctxt);
1589 if ((timing) && (!repeat)) {
1590 endTimer("Validating");
1591 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001592 }
Daniel Veillard4432df22003-09-28 18:58:27 +00001593#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001594
1595#ifdef LIBXML_DEBUG_ENABLED
1596 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001597 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001598#endif
1599
1600 /*
1601 * free it.
1602 */
Daniel Veillard48b2f892001-02-25 16:11:03 +00001603 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001604 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001605 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001606 xmlFreeDoc(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +00001607 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001608 endTimer("Freeing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001609 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001610}
1611
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001612/************************************************************************
1613 * *
1614 * Usage and Main *
1615 * *
1616 ************************************************************************/
1617
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00001618static void showVersion(const char *name) {
1619 fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
1620 fprintf(stderr, " compiled with: ");
Daniel Veillard4432df22003-09-28 18:58:27 +00001621#ifdef LIBXML_VALID_ENABLED
1622 fprintf(stderr, "DTDValid ");
1623#endif
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00001624#ifdef LIBXML_FTP_ENABLED
1625 fprintf(stderr, "FTP ");
1626#endif
1627#ifdef LIBXML_HTTP_ENABLED
1628 fprintf(stderr, "HTTP ");
1629#endif
1630#ifdef LIBXML_HTML_ENABLED
1631 fprintf(stderr, "HTML ");
1632#endif
1633#ifdef LIBXML_C14N_ENABLED
1634 fprintf(stderr, "C14N ");
1635#endif
1636#ifdef LIBXML_CATALOG_ENABLED
1637 fprintf(stderr, "Catalog ");
1638#endif
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00001639#ifdef LIBXML_XPATH_ENABLED
1640 fprintf(stderr, "XPath ");
1641#endif
1642#ifdef LIBXML_XPTR_ENABLED
1643 fprintf(stderr, "XPointer ");
1644#endif
1645#ifdef LIBXML_XINCLUDE_ENABLED
1646 fprintf(stderr, "XInclude ");
1647#endif
1648#ifdef LIBXML_ICONV_ENABLED
1649 fprintf(stderr, "Iconv ");
1650#endif
1651#ifdef DEBUG_MEMORY_LOCATION
1652 fprintf(stderr, "MemDebug ");
1653#endif
1654#ifdef LIBXML_UNICODE_ENABLED
1655 fprintf(stderr, "Unicode ");
1656#endif
1657#ifdef LIBXML_REGEXP_ENABLED
1658 fprintf(stderr, "Regexps ");
1659#endif
1660#ifdef LIBXML_AUTOMATA_ENABLED
1661 fprintf(stderr, "Automata ");
1662#endif
1663#ifdef LIBXML_SCHEMAS_ENABLED
1664 fprintf(stderr, "Schemas ");
1665#endif
Daniel Veillardce1648b2005-01-04 15:10:22 +00001666#ifdef LIBXML_MODULES_ENABLED
1667 fprintf(stderr, "Modules ");
1668#endif
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00001669 fprintf(stderr, "\n");
1670}
1671
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001672static void usage(const char *name) {
1673 printf("Usage : %s [options] XMLfiles ...\n", name);
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00001674#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001675 printf("\tParse the XML files and output the result of the parsing\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00001676#else
1677 printf("\tParse the XML files\n");
1678#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001679 printf("\t--version : display the version of the XML library used\n");
1680#ifdef LIBXML_DEBUG_ENABLED
1681 printf("\t--debug : dump a debug tree of the in-memory document\n");
1682 printf("\t--shell : run a navigating shell\n");
1683 printf("\t--debugent : debug the entities defined in the document\n");
Daniel Veillard8326e732003-01-07 00:19:07 +00001684#else
Daniel Veillard81273902003-09-30 00:43:48 +00001685#ifdef LIBXML_READER_ENABLED
Daniel Veillard8326e732003-01-07 00:19:07 +00001686 printf("\t--debug : dump the nodes content when using --stream\n");
Daniel Veillard81273902003-09-30 00:43:48 +00001687#endif /* LIBXML_READER_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001688#endif
Daniel Veillard652327a2003-09-29 18:02:38 +00001689#ifdef LIBXML_TREE_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001690 printf("\t--copy : used to test the internal copy implementation\n");
Daniel Veillard652327a2003-09-29 18:02:38 +00001691#endif /* LIBXML_TREE_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001692 printf("\t--recover : output what was parsable on broken XML documents\n");
1693 printf("\t--noent : substitute entity references by their value\n");
1694 printf("\t--noout : don't output the result tree\n");
Daniel Veillard0bff36d2004-08-31 09:37:03 +00001695 printf("\t--path 'paths': provide a set of paths for resources\n");
1696 printf("\t--load-trace : print trace of all external entites loaded\n");
Daniel Veillarde8b09e42003-05-13 22:14:13 +00001697 printf("\t--nonet : refuse to fetch DTDs or entities over network\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001698 printf("\t--htmlout : output results as HTML\n");
Daniel Veillard05c13a22001-09-09 08:38:09 +00001699 printf("\t--nowrap : do not put HTML doc wrapper\n");
Daniel Veillard4432df22003-09-28 18:58:27 +00001700#ifdef LIBXML_VALID_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001701 printf("\t--valid : validate the document in addition to std well-formed check\n");
1702 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
1703 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
Daniel Veillard66f68e72003-08-18 16:39:51 +00001704 printf("\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
Daniel Veillard4432df22003-09-28 18:58:27 +00001705#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001706 printf("\t--timing : print some timings\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001707 printf("\t--output file or -o file: save to a given file\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001708 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
1709 printf("\t--insert : ad-hoc test for valid insertions\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00001710#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001711#ifdef HAVE_ZLIB_H
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001712 printf("\t--compress : turn on gzip compression of output\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001713#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00001714#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001715#ifdef LIBXML_HTML_ENABLED
1716 printf("\t--html : use the HTML parser\n");
Daniel Veillard42fd4122003-11-04 08:47:48 +00001717 printf("\t--xmlout : force to use the XML serializer when using --html\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001718#endif
Daniel Veillard73b013f2003-09-30 12:36:01 +00001719#ifdef LIBXML_PUSH_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001720 printf("\t--push : use the push mode of the parser\n");
Daniel Veillard73b013f2003-09-30 12:36:01 +00001721#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001722#ifdef HAVE_SYS_MMAN_H
1723 printf("\t--memory : parse from memory\n");
1724#endif
Daniel Veillard87076042004-05-03 22:54:49 +00001725 printf("\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001726 printf("\t--nowarning : do not emit warnings from parser/validator\n");
1727 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
Daniel Veillarddca8cc72003-09-26 13:53:14 +00001728 printf("\t--nocdata : replace cdata section with text nodes\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00001729#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard90493a92001-08-14 14:12:47 +00001730 printf("\t--format : reformat/reindent the input\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001731 printf("\t--encode encoding : output in the given encoding\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00001732 printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
1733#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard25048d82004-08-14 22:37:54 +00001734 printf("\t--c14n: save in W3C canonical format (with comments)\n");
1735#ifdef LIBXML_C14N_ENABLED
1736#endif /* LIBXML_C14N_ENABLED */
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00001737 printf("\t--nsclean : remove redundant namespace declarations\n");
1738 printf("\t--testIO : test user I/O support\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001739#ifdef LIBXML_CATALOG_ENABLED
Daniel Veillardbd9b0e82001-11-26 10:32:08 +00001740 printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
1741 printf("\t otherwise XML Catalogs starting from \n");
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001742 printf("\t %s are activated by default\n", XML_XML_DEFAULT_CATALOG);
Daniel Veillard05c13a22001-09-09 08:38:09 +00001743 printf("\t--nocatalogs: deactivate all catalogs\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001744#endif
1745 printf("\t--auto : generate a small doc on the fly\n");
1746#ifdef LIBXML_XINCLUDE_ENABLED
1747 printf("\t--xinclude : do XInclude processing\n");
Daniel Veillardc14c3892004-08-16 12:34:50 +00001748 printf("\t--noxincludenode : same but do not generate XInclude nodes\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001749#endif
Daniel Veillardcbaf3992001-12-31 16:16:02 +00001750 printf("\t--loaddtd : fetch external DTD\n");
Daniel Veillard48da9102001-08-07 01:10:10 +00001751 printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
Daniel Veillard81273902003-09-30 00:43:48 +00001752#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00001753 printf("\t--stream : use the streaming interface to process very large files\n");
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001754 printf("\t--walker : create a reader and walk though the resulting doc\n");
Daniel Veillard81273902003-09-30 00:43:48 +00001755#endif /* LIBXML_READER_ENABLED */
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001756#ifdef LIBXML_PATTERN_ENABLED
1757 printf("\t--pattern pattern_value : test the pattern support\n");
1758#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001759 printf("\t--chkregister : verify the node registration code\n");
Daniel Veillardef4d3bc2003-02-07 12:38:22 +00001760#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard71531f32003-02-05 13:19:53 +00001761 printf("\t--relaxng schema : do RelaxNG validation against the schema\n");
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001762 printf("\t--schema schema : do validation against the WXS schema\n");
Daniel Veillard71531f32003-02-05 13:19:53 +00001763#endif
Daniel Veillarda42f25f2002-01-25 14:15:40 +00001764 printf("\nLibxml project home page: http://xmlsoft.org/\n");
1765 printf("To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001766}
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001767
1768static void registerNode(xmlNodePtr node)
1769{
1770 node->_private = malloc(sizeof(long));
1771 *(long*)node->_private = (long) 0x81726354;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00001772 nbregister++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001773}
1774
1775static void deregisterNode(xmlNodePtr node)
1776{
1777 assert(node->_private != NULL);
1778 assert(*(long*)node->_private == (long) 0x81726354);
1779 free(node->_private);
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00001780 nbregister--;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001781}
1782
Daniel Veillard4a6845d2001-01-03 13:32:39 +00001783int
1784main(int argc, char **argv) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00001785 int i, acount;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001786 int files = 0;
Daniel Veillard845cce42002-01-09 11:51:37 +00001787 int version = 0;
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00001788 const char* indent;
1789
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001790 if (argc <= 1) {
1791 usage(argv[0]);
1792 return(1);
1793 }
Daniel Veillardbe803962000-06-28 23:40:59 +00001794 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001795 for (i = 1; i < argc ; i++) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001796 if (!strcmp(argv[i], "-"))
1797 break;
1798
1799 if (argv[i][0] != '-')
1800 continue;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001801 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
1802 debug++;
Daniel Veillard56ada1d2003-01-07 11:17:25 +00001803 else
1804#ifdef LIBXML_DEBUG_ENABLED
1805 if ((!strcmp(argv[i], "-shell")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001806 (!strcmp(argv[i], "--shell"))) {
1807 shell++;
1808 noout = 1;
1809 } else
1810#endif
Daniel Veillard652327a2003-09-29 18:02:38 +00001811#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001812 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
1813 copy++;
Daniel Veillard652327a2003-09-29 18:02:38 +00001814 else
1815#endif /* LIBXML_TREE_ENABLED */
1816 if ((!strcmp(argv[i], "-recover")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00001817 (!strcmp(argv[i], "--recover"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001818 recovery++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00001819 options |= XML_PARSE_RECOVER;
1820 } else if ((!strcmp(argv[i], "-noent")) ||
1821 (!strcmp(argv[i], "--noent"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001822 noent++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00001823 options |= XML_PARSE_NOENT;
Daniel Veillarddca8cc72003-09-26 13:53:14 +00001824 } else if ((!strcmp(argv[i], "-nsclean")) ||
1825 (!strcmp(argv[i], "--nsclean"))) {
1826 options |= XML_PARSE_NSCLEAN;
1827 } else if ((!strcmp(argv[i], "-nocdata")) ||
1828 (!strcmp(argv[i], "--nocdata"))) {
1829 options |= XML_PARSE_NOCDATA;
Daniel Veillarde96a2a42003-09-24 21:23:56 +00001830 } else if ((!strcmp(argv[i], "-nodict")) ||
1831 (!strcmp(argv[i], "--nodict"))) {
1832 options |= XML_PARSE_NODICT;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00001833 } else if ((!strcmp(argv[i], "-version")) ||
Daniel Veillard845cce42002-01-09 11:51:37 +00001834 (!strcmp(argv[i], "--version"))) {
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00001835 showVersion(argv[0]);
Daniel Veillard845cce42002-01-09 11:51:37 +00001836 version = 1;
1837 } else if ((!strcmp(argv[i], "-noout")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001838 (!strcmp(argv[i], "--noout")))
1839 noout++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00001840#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001841 else if ((!strcmp(argv[i], "-o")) ||
1842 (!strcmp(argv[i], "-output")) ||
1843 (!strcmp(argv[i], "--output"))) {
1844 i++;
Daniel Veillard6e4f1c02002-04-09 09:55:20 +00001845 output = argv[i];
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001846 }
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00001847#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001848 else if ((!strcmp(argv[i], "-htmlout")) ||
1849 (!strcmp(argv[i], "--htmlout")))
1850 htmlout++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00001851 else if ((!strcmp(argv[i], "-nowrap")) ||
1852 (!strcmp(argv[i], "--nowrap")))
1853 nowrap++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001854#ifdef LIBXML_HTML_ENABLED
1855 else if ((!strcmp(argv[i], "-html")) ||
1856 (!strcmp(argv[i], "--html"))) {
1857 html++;
1858 }
Daniel Veillard42fd4122003-11-04 08:47:48 +00001859 else if ((!strcmp(argv[i], "-xmlout")) ||
1860 (!strcmp(argv[i], "--xmlout"))) {
1861 xmlout++;
1862 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001863#endif /* LIBXML_HTML_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001864 else if ((!strcmp(argv[i], "-loaddtd")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00001865 (!strcmp(argv[i], "--loaddtd"))) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001866 loaddtd++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00001867 options |= XML_PARSE_DTDLOAD;
1868 } else if ((!strcmp(argv[i], "-dtdattr")) ||
Daniel Veillard48da9102001-08-07 01:10:10 +00001869 (!strcmp(argv[i], "--dtdattr"))) {
1870 loaddtd++;
1871 dtdattrs++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00001872 options |= XML_PARSE_DTDATTR;
Daniel Veillard4432df22003-09-28 18:58:27 +00001873 }
1874#ifdef LIBXML_VALID_ENABLED
1875 else if ((!strcmp(argv[i], "-valid")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00001876 (!strcmp(argv[i], "--valid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001877 valid++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00001878 options |= XML_PARSE_DTDVALID;
1879 } else if ((!strcmp(argv[i], "-postvalid")) ||
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001880 (!strcmp(argv[i], "--postvalid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001881 postvalid++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001882 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00001883 options |= XML_PARSE_DTDLOAD;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001884 } else if ((!strcmp(argv[i], "-dtdvalid")) ||
Daniel Veillardcd429612000-10-11 15:57:05 +00001885 (!strcmp(argv[i], "--dtdvalid"))) {
1886 i++;
1887 dtdvalid = argv[i];
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001888 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00001889 options |= XML_PARSE_DTDLOAD;
Daniel Veillard66f68e72003-08-18 16:39:51 +00001890 } else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
1891 (!strcmp(argv[i], "--dtdvalidfpi"))) {
1892 i++;
1893 dtdvalidfpi = argv[i];
1894 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00001895 options |= XML_PARSE_DTDLOAD;
Daniel Veillardcd429612000-10-11 15:57:05 +00001896 }
Daniel Veillard4432df22003-09-28 18:58:27 +00001897#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard29e43992001-12-13 22:21:58 +00001898 else if ((!strcmp(argv[i], "-dropdtd")) ||
1899 (!strcmp(argv[i], "--dropdtd")))
1900 dropdtd++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001901 else if ((!strcmp(argv[i], "-insert")) ||
1902 (!strcmp(argv[i], "--insert")))
1903 insert++;
Daniel Veillard48b2f892001-02-25 16:11:03 +00001904 else if ((!strcmp(argv[i], "-timing")) ||
1905 (!strcmp(argv[i], "--timing")))
1906 timing++;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001907 else if ((!strcmp(argv[i], "-auto")) ||
1908 (!strcmp(argv[i], "--auto")))
1909 generate++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001910 else if ((!strcmp(argv[i], "-repeat")) ||
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001911 (!strcmp(argv[i], "--repeat"))) {
1912 if (repeat)
1913 repeat *= 10;
1914 else
1915 repeat = 100;
Daniel Veillard73b013f2003-09-30 12:36:01 +00001916 }
1917#ifdef LIBXML_PUSH_ENABLED
1918 else if ((!strcmp(argv[i], "-push")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001919 (!strcmp(argv[i], "--push")))
1920 push++;
Daniel Veillard73b013f2003-09-30 12:36:01 +00001921#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillard46e370e2000-07-21 20:32:03 +00001922#ifdef HAVE_SYS_MMAN_H
1923 else if ((!strcmp(argv[i], "-memory")) ||
1924 (!strcmp(argv[i], "--memory")))
1925 memory++;
1926#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +00001927 else if ((!strcmp(argv[i], "-testIO")) ||
1928 (!strcmp(argv[i], "--testIO")))
1929 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00001930#ifdef LIBXML_XINCLUDE_ENABLED
1931 else if ((!strcmp(argv[i], "-xinclude")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00001932 (!strcmp(argv[i], "--xinclude"))) {
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00001933 xinclude++;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001934 options |= XML_PARSE_XINCLUDE;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00001935 }
Daniel Veillardc14c3892004-08-16 12:34:50 +00001936 else if ((!strcmp(argv[i], "-noxincludenode")) ||
1937 (!strcmp(argv[i], "--noxincludenode"))) {
1938 xinclude++;
1939 options |= XML_PARSE_XINCLUDE;
1940 options |= XML_PARSE_NOXINCNODE;
1941 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00001942#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00001943#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001944#ifdef HAVE_ZLIB_H
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001945 else if ((!strcmp(argv[i], "-compress")) ||
1946 (!strcmp(argv[i], "--compress"))) {
1947 compress++;
1948 xmlSetCompressMode(9);
1949 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001950#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00001951#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001952 else if ((!strcmp(argv[i], "-nowarning")) ||
1953 (!strcmp(argv[i], "--nowarning"))) {
1954 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001955 xmlPedanticParserDefault(0);
Daniel Veillard16fa96c2003-09-23 21:50:54 +00001956 options |= XML_PARSE_NOWARNING;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001957 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001958 else if ((!strcmp(argv[i], "-pedantic")) ||
1959 (!strcmp(argv[i], "--pedantic"))) {
1960 xmlGetWarningsDefaultValue = 1;
1961 xmlPedanticParserDefault(1);
Daniel Veillard16fa96c2003-09-23 21:50:54 +00001962 options |= XML_PARSE_PEDANTIC;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001963 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00001964#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001965 else if ((!strcmp(argv[i], "-debugent")) ||
1966 (!strcmp(argv[i], "--debugent"))) {
1967 debugent++;
1968 xmlParserDebugEntities = 1;
1969 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00001970#endif
Daniel Veillard25048d82004-08-14 22:37:54 +00001971#ifdef LIBXML_C14N_ENABLED
1972 else if ((!strcmp(argv[i], "-c14n")) ||
1973 (!strcmp(argv[i], "--c14n"))) {
1974 canonical++;
1975 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
1976 }
1977#endif
Daniel Veillard81418e32001-05-22 15:08:55 +00001978#ifdef LIBXML_CATALOG_ENABLED
1979 else if ((!strcmp(argv[i], "-catalogs")) ||
1980 (!strcmp(argv[i], "--catalogs"))) {
Daniel Veillarde2940dd2001-08-22 00:06:49 +00001981 catalogs++;
1982 } else if ((!strcmp(argv[i], "-nocatalogs")) ||
1983 (!strcmp(argv[i], "--nocatalogs"))) {
1984 nocatalogs++;
Daniel Veillard81418e32001-05-22 15:08:55 +00001985 }
1986#endif
Daniel Veillardbe803962000-06-28 23:40:59 +00001987 else if ((!strcmp(argv[i], "-encode")) ||
1988 (!strcmp(argv[i], "--encode"))) {
1989 i++;
1990 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001991 /*
1992 * OK it's for testing purposes
1993 */
1994 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +00001995 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001996 else if ((!strcmp(argv[i], "-noblanks")) ||
1997 (!strcmp(argv[i], "--noblanks"))) {
1998 noblanks++;
1999 xmlKeepBlanksDefault(0);
Daniel Veillard90493a92001-08-14 14:12:47 +00002000 }
Daniel Veillard87076042004-05-03 22:54:49 +00002001 else if ((!strcmp(argv[i], "-maxmem")) ||
2002 (!strcmp(argv[i], "--maxmem"))) {
2003 i++;
2004 if (sscanf(argv[i], "%d", &maxmem) == 1) {
2005 xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc,
2006 myStrdupFunc);
2007 } else {
2008 maxmem = 0;
2009 }
2010 }
Daniel Veillard90493a92001-08-14 14:12:47 +00002011 else if ((!strcmp(argv[i], "-format")) ||
2012 (!strcmp(argv[i], "--format"))) {
2013 noblanks++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002014#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard90493a92001-08-14 14:12:47 +00002015 format++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002016#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard90493a92001-08-14 14:12:47 +00002017 xmlKeepBlanksDefault(0);
Daniel Veillard7704fb12003-01-03 16:19:51 +00002018 }
Daniel Veillard81273902003-09-30 00:43:48 +00002019#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00002020 else if ((!strcmp(argv[i], "-stream")) ||
2021 (!strcmp(argv[i], "--stream"))) {
2022 stream++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00002023 }
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002024 else if ((!strcmp(argv[i], "-walker")) ||
2025 (!strcmp(argv[i], "--walker"))) {
2026 walker++;
2027 noout++;
2028 }
Daniel Veillard81273902003-09-30 00:43:48 +00002029#endif /* LIBXML_READER_ENABLED */
2030#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +00002031 else if ((!strcmp(argv[i], "-sax1")) ||
2032 (!strcmp(argv[i], "--sax1"))) {
2033 sax1++;
2034 }
Daniel Veillard81273902003-09-30 00:43:48 +00002035#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillard8a1b1852003-01-05 22:37:17 +00002036 else if ((!strcmp(argv[i], "-chkregister")) ||
2037 (!strcmp(argv[i], "--chkregister"))) {
2038 chkregister++;
Daniel Veillard71531f32003-02-05 13:19:53 +00002039#ifdef LIBXML_SCHEMAS_ENABLED
2040 } else if ((!strcmp(argv[i], "-relaxng")) ||
2041 (!strcmp(argv[i], "--relaxng"))) {
2042 i++;
2043 relaxng = argv[i];
2044 noent++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002045 options |= XML_PARSE_NOENT;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002046 } else if ((!strcmp(argv[i], "-schema")) ||
2047 (!strcmp(argv[i], "--schema"))) {
2048 i++;
2049 schema = argv[i];
2050 noent++;
Daniel Veillard71531f32003-02-05 13:19:53 +00002051#endif
Daniel Veillarde8b09e42003-05-13 22:14:13 +00002052 } else if ((!strcmp(argv[i], "-nonet")) ||
2053 (!strcmp(argv[i], "--nonet"))) {
Daniel Veillard61b93382003-11-03 14:28:31 +00002054 options |= XML_PARSE_NONET;
Daniel Veillard0bff36d2004-08-31 09:37:03 +00002055 } else if ((!strcmp(argv[i], "-load-trace")) ||
2056 (!strcmp(argv[i], "--load-trace"))) {
2057 load_trace++;
2058 } else if ((!strcmp(argv[i], "-path")) ||
2059 (!strcmp(argv[i], "--path"))) {
2060 i++;
2061 parsePath(BAD_CAST argv[i]);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00002062#ifdef LIBXML_PATTERN_ENABLED
2063 } else if ((!strcmp(argv[i], "-pattern")) ||
2064 (!strcmp(argv[i], "--pattern"))) {
2065 i++;
2066 pattern = argv[i];
2067#endif
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002068 } else {
2069 fprintf(stderr, "Unknown option %s\n", argv[i]);
2070 usage(argv[0]);
2071 return(1);
2072 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002073 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00002074
2075#ifdef LIBXML_CATALOG_ENABLED
2076 if (nocatalogs == 0) {
2077 if (catalogs) {
2078 const char *catal;
2079
2080 catal = getenv("SGML_CATALOG_FILES");
Daniel Veillard6c5f9d12001-08-25 13:33:14 +00002081 if (catal != NULL) {
2082 xmlLoadCatalogs(catal);
2083 } else {
2084 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
2085 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00002086 }
2087 }
2088#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00002089
Daniel Veillard81273902003-09-30 00:43:48 +00002090#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +00002091 if (sax1)
2092 xmlSAXDefaultVersion(1);
2093 else
2094 xmlSAXDefaultVersion(2);
Daniel Veillard81273902003-09-30 00:43:48 +00002095#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillard07cb8222003-09-10 10:51:05 +00002096
Daniel Veillard8a1b1852003-01-05 22:37:17 +00002097 if (chkregister) {
2098 xmlRegisterNodeDefault(registerNode);
2099 xmlDeregisterNodeDefault(deregisterNode);
2100 }
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00002101
2102 indent = getenv("XMLLINT_INDENT");
2103 if(indent != NULL) {
2104 xmlTreeIndentString = indent;
2105 }
2106
Daniel Veillard8a1b1852003-01-05 22:37:17 +00002107
Daniel Veillard0bff36d2004-08-31 09:37:03 +00002108 defaultEntityLoader = xmlGetExternalEntityLoader();
2109 xmlSetExternalEntityLoader(xmllintExternalEntityLoader);
2110
Daniel Veillardd9bad132001-07-23 19:39:43 +00002111 xmlLineNumbersDefault(1);
Daniel Veillard48da9102001-08-07 01:10:10 +00002112 if (loaddtd != 0)
2113 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
2114 if (dtdattrs)
2115 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002116 if (noent != 0) xmlSubstituteEntitiesDefault(1);
Daniel Veillard4432df22003-09-28 18:58:27 +00002117#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002118 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
Daniel Veillard4432df22003-09-28 18:58:27 +00002119#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002120 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00002121 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002122 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00002123 xmlGenericError(xmlGenericErrorContext,
2124 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
2125 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002126 "<html><head><title>%s output</title></head>\n",
2127 argv[0]);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00002128 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002129 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
2130 argv[0]);
2131 }
Daniel Veillard71531f32003-02-05 13:19:53 +00002132
2133#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard81273902003-09-30 00:43:48 +00002134 if ((relaxng != NULL)
2135#ifdef LIBXML_READER_ENABLED
2136 && (stream == 0)
2137#endif /* LIBXML_READER_ENABLED */
2138 ) {
Daniel Veillard71531f32003-02-05 13:19:53 +00002139 xmlRelaxNGParserCtxtPtr ctxt;
2140
Daniel Veillardce192eb2003-04-16 15:58:05 +00002141 /* forces loading the DTDs */
2142 xmlLoadExtDtdDefaultValue |= 1;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002143 options |= XML_PARSE_DTDLOAD;
Daniel Veillard42f12e92003-03-07 18:32:59 +00002144 if (timing) {
2145 startTimer();
2146 }
Daniel Veillard71531f32003-02-05 13:19:53 +00002147 ctxt = xmlRelaxNGNewParserCtxt(relaxng);
2148 xmlRelaxNGSetParserErrors(ctxt,
2149 (xmlRelaxNGValidityErrorFunc) fprintf,
2150 (xmlRelaxNGValidityWarningFunc) fprintf,
2151 stderr);
2152 relaxngschemas = xmlRelaxNGParse(ctxt);
Daniel Veillardce192eb2003-04-16 15:58:05 +00002153 if (relaxngschemas == NULL) {
2154 xmlGenericError(xmlGenericErrorContext,
2155 "Relax-NG schema %s failed to compile\n", relaxng);
William M. Brack8304d872004-06-08 13:29:32 +00002156 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillardce192eb2003-04-16 15:58:05 +00002157 relaxng = NULL;
2158 }
Daniel Veillard71531f32003-02-05 13:19:53 +00002159 xmlRelaxNGFreeParserCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00002160 if (timing) {
2161 endTimer("Compiling the schemas");
2162 }
Daniel Veillardebe25d42004-03-25 09:35:49 +00002163 } else if ((schema != NULL)
2164#ifdef LIBXML_READER_ENABLED
2165 && (stream == 0)
2166#endif
2167 ) {
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002168 xmlSchemaParserCtxtPtr ctxt;
2169
2170 if (timing) {
2171 startTimer();
2172 }
2173 ctxt = xmlSchemaNewParserCtxt(schema);
2174 xmlSchemaSetParserErrors(ctxt,
2175 (xmlSchemaValidityErrorFunc) fprintf,
2176 (xmlSchemaValidityWarningFunc) fprintf,
2177 stderr);
2178 wxschemas = xmlSchemaParse(ctxt);
2179 if (wxschemas == NULL) {
2180 xmlGenericError(xmlGenericErrorContext,
2181 "WXS schema %s failed to compile\n", schema);
William M. Brack8304d872004-06-08 13:29:32 +00002182 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002183 schema = NULL;
2184 }
2185 xmlSchemaFreeParserCtxt(ctxt);
2186 if (timing) {
2187 endTimer("Compiling the schemas");
2188 }
Daniel Veillard71531f32003-02-05 13:19:53 +00002189 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00002190#endif /* LIBXML_SCHEMAS_ENABLED */
2191#ifdef LIBXML_PATTERN_ENABLED
2192 if (pattern != NULL) {
Daniel Veillardffa7b7e2003-12-05 16:10:21 +00002193 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00002194 if (patternc == NULL) {
2195 xmlGenericError(xmlGenericErrorContext,
2196 "Pattern %s failed to compile\n", pattern);
William M. Brack8304d872004-06-08 13:29:32 +00002197 progresult = XMLLINT_ERR_SCHEMAPAT;
Daniel Veillardb3de70c2003-12-02 22:32:15 +00002198 pattern = NULL;
2199 }
2200 }
2201#endif /* LIBXML_PATTERN_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002202 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +00002203 if ((!strcmp(argv[i], "-encode")) ||
2204 (!strcmp(argv[i], "--encode"))) {
2205 i++;
2206 continue;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002207 } else if ((!strcmp(argv[i], "-o")) ||
2208 (!strcmp(argv[i], "-output")) ||
2209 (!strcmp(argv[i], "--output"))) {
2210 i++;
2211 continue;
Daniel Veillardbe803962000-06-28 23:40:59 +00002212 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002213#ifdef LIBXML_VALID_ENABLED
Daniel Veillardcd429612000-10-11 15:57:05 +00002214 if ((!strcmp(argv[i], "-dtdvalid")) ||
2215 (!strcmp(argv[i], "--dtdvalid"))) {
2216 i++;
2217 continue;
Daniel Veillard0bff36d2004-08-31 09:37:03 +00002218 }
2219 if ((!strcmp(argv[i], "-path")) ||
2220 (!strcmp(argv[i], "--path"))) {
2221 i++;
2222 continue;
Daniel Veillardcd429612000-10-11 15:57:05 +00002223 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00002224 if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
2225 (!strcmp(argv[i], "--dtdvalidfpi"))) {
2226 i++;
2227 continue;
2228 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002229#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard71531f32003-02-05 13:19:53 +00002230 if ((!strcmp(argv[i], "-relaxng")) ||
2231 (!strcmp(argv[i], "--relaxng"))) {
2232 i++;
2233 continue;
2234 }
Daniel Veillard87076042004-05-03 22:54:49 +00002235 if ((!strcmp(argv[i], "-maxmem")) ||
2236 (!strcmp(argv[i], "--maxmem"))) {
2237 i++;
2238 continue;
2239 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002240 if ((!strcmp(argv[i], "-schema")) ||
2241 (!strcmp(argv[i], "--schema"))) {
2242 i++;
2243 continue;
2244 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00002245#ifdef LIBXML_PATTERN_ENABLED
2246 if ((!strcmp(argv[i], "-pattern")) ||
2247 (!strcmp(argv[i], "--pattern"))) {
2248 i++;
2249 continue;
2250 }
2251#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00002252 if ((timing) && (repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00002253 startTimer();
Daniel Veillardcbaf3992001-12-31 16:16:02 +00002254 /* Remember file names. "-" means stdin. <sven@zen.org> */
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002255 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002256 if (repeat) {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002257 xmlParserCtxtPtr ctxt = NULL;
2258
2259 for (acount = 0;acount < repeat;acount++) {
Daniel Veillard81273902003-09-30 00:43:48 +00002260#ifdef LIBXML_READER_ENABLED
Daniel Veillard198c1bf2003-10-20 17:07:41 +00002261 if (stream != 0) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00002262 streamFile(argv[i]);
Daniel Veillard198c1bf2003-10-20 17:07:41 +00002263 } else {
Daniel Veillard81273902003-09-30 00:43:48 +00002264#endif /* LIBXML_READER_ENABLED */
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002265 if (ctxt == NULL)
2266 ctxt = xmlNewParserCtxt();
2267 parseAndPrintFile(argv[i], ctxt);
Daniel Veillard81273902003-09-30 00:43:48 +00002268#ifdef LIBXML_READER_ENABLED
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002269 }
Daniel Veillard81273902003-09-30 00:43:48 +00002270#endif /* LIBXML_READER_ENABLED */
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002271 }
2272 if (ctxt != NULL)
2273 xmlFreeParserCtxt(ctxt);
Daniel Veillard7704fb12003-01-03 16:19:51 +00002274 } else {
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00002275 nbregister = 0;
2276
Daniel Veillard81273902003-09-30 00:43:48 +00002277#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00002278 if (stream != 0)
2279 streamFile(argv[i]);
2280 else
Daniel Veillard81273902003-09-30 00:43:48 +00002281#endif /* LIBXML_READER_ENABLED */
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002282 parseAndPrintFile(argv[i], NULL);
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00002283
2284 if ((chkregister) && (nbregister != 0)) {
2285 fprintf(stderr, "Registration count off: %d\n", nbregister);
William M. Brack8304d872004-06-08 13:29:32 +00002286 progresult = XMLLINT_ERR_RDREGIS;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00002287 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00002288 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002289 files ++;
Daniel Veillarda7866932001-12-04 13:14:44 +00002290 if ((timing) && (repeat)) {
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00002291 endTimer("%d iterations", repeat);
Daniel Veillarda7866932001-12-04 13:14:44 +00002292 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002293 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002294 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002295 if (generate)
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002296 parseAndPrintFile(NULL, NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002297 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00002298 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002299 }
Daniel Veillard845cce42002-01-09 11:51:37 +00002300 if ((files == 0) && (!generate) && (version == 0)) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002301 usage(argv[0]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002302 }
Daniel Veillard71531f32003-02-05 13:19:53 +00002303#ifdef LIBXML_SCHEMAS_ENABLED
2304 if (relaxngschemas != NULL)
2305 xmlRelaxNGFree(relaxngschemas);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002306 if (wxschemas != NULL)
2307 xmlSchemaFree(wxschemas);
Daniel Veillard71531f32003-02-05 13:19:53 +00002308 xmlRelaxNGCleanupTypes();
2309#endif
Daniel Veillardb3de70c2003-12-02 22:32:15 +00002310#ifdef LIBXML_PATTERN_ENABLED
2311 if (patternc != NULL)
2312 xmlFreePattern(patternc);
2313#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002314 xmlCleanupParser();
2315 xmlMemoryDump();
2316
Daniel Veillardf7cd4812001-02-23 18:44:52 +00002317 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002318}
Daniel Veillard88a172f2000-08-04 18:23:10 +00002319