blob: 77c1e62f48041537554a184145364d868fb85091 [file] [log] [blame]
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001/*
2 * xmllint.c : a small tester program for XML input.
3 *
4 * See Copyright for the status of this software.
5 *
Daniel Veillardc5d64342001-06-24 12:13:24 +00006 * daniel@veillard.com
Daniel Veillardce8b83b2000-04-05 18:38:42 +00007 */
8
Bjorn Reese70a9da52001-04-21 16:57:29 +00009#include "libxml.h"
Daniel Veillardce8b83b2000-04-05 18:38:42 +000010
Daniel Veillardce8b83b2000-04-05 18:38:42 +000011#include <string.h>
Daniel Veillardce8b83b2000-04-05 18:38:42 +000012#include <stdarg.h>
Daniel Veillard8a1b1852003-01-05 22:37:17 +000013#include <assert.h>
14
Daniel Veillard3c5ed912002-01-08 10:36:16 +000015#if defined (_WIN32) && !defined(__CYGWIN__)
Daniel Veillard07cb8222003-09-10 10:51:05 +000016#if defined (_MSC_VER) || defined(__BORLANDC__)
Daniel Veillard2d90de42001-04-16 17:46:18 +000017#include <winsock2.h>
18#pragma comment(lib, "ws2_32.lib")
19#define gettimeofday(p1,p2)
20#endif /* _MSC_VER */
Igor Zlatkovic19b87642003-08-28 12:32:04 +000021#endif /* _WIN32 */
22
Daniel Veillarded472f32001-12-13 08:48:14 +000023#ifdef HAVE_SYS_TIME_H
Daniel Veillard48b2f892001-02-25 16:11:03 +000024#include <sys/time.h>
Daniel Veillarded472f32001-12-13 08:48:14 +000025#endif
Daniel Veillard01db67c2001-12-18 07:09:59 +000026#ifdef HAVE_TIME_H
27#include <time.h>
28#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +000029
Daniel Veillard1638a472003-08-14 01:23:25 +000030#ifdef __MINGW32__
31#define _WINSOCKAPI_
32#include <wsockcompat.h>
33#include <winsock2.h>
Daniel Veillardc284c642005-03-31 10:24:24 +000034#undef XML_SOCKLEN_T
35#define XML_SOCKLEN_T unsigned int
Daniel Veillard1638a472003-08-14 01:23:25 +000036#endif
37
Daniel Veillard90bc3712002-03-07 15:12:58 +000038#ifdef HAVE_SYS_TIMEB_H
39#include <sys/timeb.h>
40#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000041
42#ifdef HAVE_SYS_TYPES_H
43#include <sys/types.h>
44#endif
45#ifdef HAVE_SYS_STAT_H
46#include <sys/stat.h>
47#endif
48#ifdef HAVE_FCNTL_H
49#include <fcntl.h>
50#endif
51#ifdef HAVE_UNISTD_H
52#include <unistd.h>
53#endif
Daniel Veillard46e370e2000-07-21 20:32:03 +000054#ifdef HAVE_SYS_MMAN_H
55#include <sys/mman.h>
Daniel Veillard87b95392000-08-12 21:12:04 +000056/* seems needed for Solaris */
57#ifndef MAP_FAILED
58#define MAP_FAILED ((void *) -1)
59#endif
Daniel Veillard46e370e2000-07-21 20:32:03 +000060#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000061#ifdef HAVE_STDLIB_H
62#include <stdlib.h>
63#endif
64#ifdef HAVE_LIBREADLINE
65#include <readline/readline.h>
66#ifdef HAVE_LIBHISTORY
67#include <readline/history.h>
68#endif
69#endif
70
71#include <libxml/xmlmemory.h>
72#include <libxml/parser.h>
73#include <libxml/parserInternals.h>
74#include <libxml/HTMLparser.h>
75#include <libxml/HTMLtree.h>
76#include <libxml/tree.h>
77#include <libxml/xpath.h>
78#include <libxml/debugXML.h>
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +000079#include <libxml/xmlerror.h>
Daniel Veillard9e8bfae2000-11-06 16:43:11 +000080#ifdef LIBXML_XINCLUDE_ENABLED
81#include <libxml/xinclude.h>
82#endif
Daniel Veillard81418e32001-05-22 15:08:55 +000083#ifdef LIBXML_CATALOG_ENABLED
84#include <libxml/catalog.h>
85#endif
Daniel Veillard3c01b1d2001-10-17 15:58:35 +000086#include <libxml/globals.h>
Daniel Veillard7704fb12003-01-03 16:19:51 +000087#include <libxml/xmlreader.h>
Daniel Veillardd4501d72005-07-24 14:27:16 +000088#ifdef LIBXML_SCHEMATRON_ENABLED
89#include <libxml/schematron.h>
90#endif
Daniel Veillard71531f32003-02-05 13:19:53 +000091#ifdef LIBXML_SCHEMAS_ENABLED
92#include <libxml/relaxng.h>
Daniel Veillard75bb3bb2003-05-12 15:25:56 +000093#include <libxml/xmlschemas.h>
Daniel Veillard71531f32003-02-05 13:19:53 +000094#endif
Daniel Veillardb3de70c2003-12-02 22:32:15 +000095#ifdef LIBXML_PATTERN_ENABLED
96#include <libxml/pattern.h>
97#endif
Daniel Veillard6ebf3c42004-08-22 13:11:39 +000098#ifdef LIBXML_C14N_ENABLED
99#include <libxml/c14n.h>
100#endif
Daniel Veillarddab39b52006-10-16 23:22:10 +0000101#ifdef LIBXML_OUTPUT_ENABLED
102#include <libxml/xmlsave.h>
103#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000104
Daniel Veillard3be27512003-01-26 19:49:04 +0000105#ifndef XML_XML_DEFAULT_CATALOG
106#define XML_XML_DEFAULT_CATALOG "file:///etc/xml/catalog"
107#endif
108
William M. Brack8304d872004-06-08 13:29:32 +0000109typedef enum {
110 XMLLINT_RETURN_OK = 0, /* No error */
111 XMLLINT_ERR_UNCLASS, /* Unclassified */
112 XMLLINT_ERR_DTD, /* Error in DTD */
113 XMLLINT_ERR_VALID, /* Validation error */
114 XMLLINT_ERR_RDFILE, /* CtxtReadFile error */
115 XMLLINT_ERR_SCHEMACOMP, /* Schema compilation */
116 XMLLINT_ERR_OUT, /* Error writing output */
117 XMLLINT_ERR_SCHEMAPAT, /* Error in schema pattern */
118 XMLLINT_ERR_RDREGIS, /* Error in Reader registration */
119 XMLLINT_ERR_MEM /* Out of memory error */
120} xmllintReturnCode;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000121#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000122static int shell = 0;
123static int debugent = 0;
124#endif
Daniel Veillard8326e732003-01-07 00:19:07 +0000125static int debug = 0;
Daniel Veillard87076042004-05-03 22:54:49 +0000126static int maxmem = 0;
Daniel Veillard652327a2003-09-29 18:02:38 +0000127#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000128static int copy = 0;
Daniel Veillard652327a2003-09-29 18:02:38 +0000129#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000130static int recovery = 0;
131static int noent = 0;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +0000132static int noblanks = 0;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000133static int noout = 0;
134static int nowrap = 0;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +0000135#ifdef LIBXML_OUTPUT_ENABLED
136static int format = 0;
137static const char *output = NULL;
138static int compress = 0;
Daniel Veillarddab39b52006-10-16 23:22:10 +0000139static int oldout = 0;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +0000140#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard4432df22003-09-28 18:58:27 +0000141#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000142static int valid = 0;
143static int postvalid = 0;
Daniel Veillardcd429612000-10-11 15:57:05 +0000144static char * dtdvalid = NULL;
Daniel Veillard66f68e72003-08-18 16:39:51 +0000145static char * dtdvalidfpi = NULL;
Daniel Veillard4432df22003-09-28 18:58:27 +0000146#endif
Daniel Veillard71531f32003-02-05 13:19:53 +0000147#ifdef LIBXML_SCHEMAS_ENABLED
148static char * relaxng = NULL;
149static xmlRelaxNGPtr relaxngschemas = NULL;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +0000150static char * schema = NULL;
151static xmlSchemaPtr wxschemas = NULL;
Daniel Veillard71531f32003-02-05 13:19:53 +0000152#endif
Daniel Veillard8c6e6532005-09-08 21:39:47 +0000153#ifdef LIBXML_SCHEMATRON_ENABLED
Daniel Veillardd4501d72005-07-24 14:27:16 +0000154static char * schematron = NULL;
155static xmlSchematronPtr wxschematron = NULL;
156#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000157static int repeat = 0;
158static int insert = 0;
Daniel Veillard656ce942004-04-30 23:11:45 +0000159#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000160static int html = 0;
Daniel Veillard42fd4122003-11-04 08:47:48 +0000161static int xmlout = 0;
Daniel Veillard4432df22003-09-28 18:58:27 +0000162#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000163static int htmlout = 0;
Daniel Veillard73b013f2003-09-30 12:36:01 +0000164#ifdef LIBXML_PUSH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000165static int push = 0;
Daniel Veillard73b013f2003-09-30 12:36:01 +0000166#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillard46e370e2000-07-21 20:32:03 +0000167#ifdef HAVE_SYS_MMAN_H
168static int memory = 0;
169#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +0000170static int testIO = 0;
Daniel Veillardbe803962000-06-28 23:40:59 +0000171static char *encoding = NULL;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000172#ifdef LIBXML_XINCLUDE_ENABLED
173static int xinclude = 0;
174#endif
Daniel Veillard48da9102001-08-07 01:10:10 +0000175static int dtdattrs = 0;
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000176static int loaddtd = 0;
William M. Brack8304d872004-06-08 13:29:32 +0000177static xmllintReturnCode progresult = XMLLINT_RETURN_OK;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000178static int timing = 0;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000179static int generate = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000180static int dropdtd = 0;
Daniel Veillarde2940dd2001-08-22 00:06:49 +0000181#ifdef LIBXML_CATALOG_ENABLED
182static int catalogs = 0;
183static int nocatalogs = 0;
184#endif
Daniel Veillard25048d82004-08-14 22:37:54 +0000185#ifdef LIBXML_C14N_ENABLED
186static int canonical = 0;
Aleksey Sanin2650df12005-06-06 17:16:50 +0000187static int exc_canonical = 0;
Daniel Veillard25048d82004-08-14 22:37:54 +0000188#endif
Daniel Veillard81273902003-09-30 00:43:48 +0000189#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +0000190static int stream = 0;
Daniel Veillard7899c5c2003-11-03 12:31:38 +0000191static int walker = 0;
Daniel Veillard81273902003-09-30 00:43:48 +0000192#endif /* LIBXML_READER_ENABLED */
Daniel Veillard8a1b1852003-01-05 22:37:17 +0000193static int chkregister = 0;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +0000194static int nbregister = 0;
Daniel Veillard81273902003-09-30 00:43:48 +0000195#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +0000196static int sax1 = 0;
Daniel Veillard81273902003-09-30 00:43:48 +0000197#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillardb3de70c2003-12-02 22:32:15 +0000198#ifdef LIBXML_PATTERN_ENABLED
199static const char *pattern = NULL;
200static xmlPatternPtr patternc = NULL;
Daniel Veillard2fc6df92005-01-30 18:42:55 +0000201static xmlStreamCtxtPtr patstream = NULL;
Daniel Veillardb3de70c2003-12-02 22:32:15 +0000202#endif
Daniel Veillard8874b942005-08-25 13:19:21 +0000203static int options = XML_PARSE_COMPACT;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000204static int sax = 0;
Daniel Veillard7e5c3f42008-07-29 16:12:31 +0000205static int oldxml10 = 0;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +0000206
Daniel Veillard87076042004-05-03 22:54:49 +0000207/************************************************************************
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000208 * *
209 * Entity loading control and customization. *
210 * *
211 ************************************************************************/
212#define MAX_PATHS 64
Daniel Veillarded121382007-04-17 12:33:19 +0000213#ifdef _WIN32
214# define PATH_SEPARATOR ';'
215#else
216# define PATH_SEPARATOR ':'
217#endif
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000218static xmlChar *paths[MAX_PATHS + 1];
219static int nbpaths = 0;
220static int load_trace = 0;
221
222static
223void parsePath(const xmlChar *path) {
224 const xmlChar *cur;
225
226 if (path == NULL)
227 return;
228 while (*path != 0) {
229 if (nbpaths >= MAX_PATHS) {
230 fprintf(stderr, "MAX_PATHS reached: too many paths\n");
231 return;
232 }
233 cur = path;
Daniel Veillarded121382007-04-17 12:33:19 +0000234 while ((*cur == ' ') || (*cur == PATH_SEPARATOR))
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000235 cur++;
236 path = cur;
Daniel Veillarded121382007-04-17 12:33:19 +0000237 while ((*cur != 0) && (*cur != ' ') && (*cur != PATH_SEPARATOR))
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000238 cur++;
239 if (cur != path) {
240 paths[nbpaths] = xmlStrndup(path, cur - path);
241 if (paths[nbpaths] != NULL)
242 nbpaths++;
243 path = cur;
244 }
245 }
246}
247
Daniel Veillard24505b02005-07-28 23:49:35 +0000248static xmlExternalEntityLoader defaultEntityLoader = NULL;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000249
250static xmlParserInputPtr
251xmllintExternalEntityLoader(const char *URL, const char *ID,
252 xmlParserCtxtPtr ctxt) {
253 xmlParserInputPtr ret;
254 warningSAXFunc warning = NULL;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000255 errorSAXFunc err = NULL;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000256
257 int i;
258 const char *lastsegment = URL;
259 const char *iter = URL;
260
Daniel Veillard5608b172008-01-11 06:53:15 +0000261 if ((nbpaths > 0) && (iter != NULL)) {
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000262 while (*iter != 0) {
263 if (*iter == '/')
264 lastsegment = iter + 1;
265 iter++;
266 }
267 }
268
269 if ((ctxt != NULL) && (ctxt->sax != NULL)) {
270 warning = ctxt->sax->warning;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000271 err = ctxt->sax->error;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000272 ctxt->sax->warning = NULL;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000273 ctxt->sax->error = NULL;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000274 }
275
276 if (defaultEntityLoader != NULL) {
277 ret = defaultEntityLoader(URL, ID, ctxt);
278 if (ret != NULL) {
279 if (warning != NULL)
280 ctxt->sax->warning = warning;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000281 if (err != NULL)
282 ctxt->sax->error = err;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000283 if (load_trace) {
284 fprintf \
285 (stderr,
286 "Loaded URL=\"%s\" ID=\"%s\"\n",
287 URL ? URL : "(null)",
288 ID ? ID : "(null)");
289 }
290 return(ret);
291 }
292 }
293 for (i = 0;i < nbpaths;i++) {
294 xmlChar *newURL;
295
296 newURL = xmlStrdup((const xmlChar *) paths[i]);
297 newURL = xmlStrcat(newURL, (const xmlChar *) "/");
298 newURL = xmlStrcat(newURL, (const xmlChar *) lastsegment);
299 if (newURL != NULL) {
300 ret = defaultEntityLoader((const char *)newURL, ID, ctxt);
301 if (ret != NULL) {
302 if (warning != NULL)
303 ctxt->sax->warning = warning;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000304 if (err != NULL)
305 ctxt->sax->error = err;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000306 if (load_trace) {
307 fprintf \
308 (stderr,
309 "Loaded URL=\"%s\" ID=\"%s\"\n",
310 newURL,
311 ID ? ID : "(null)");
312 }
313 xmlFree(newURL);
314 return(ret);
315 }
316 xmlFree(newURL);
317 }
318 }
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000319 if (err != NULL)
320 ctxt->sax->error = err;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000321 if (warning != NULL) {
322 ctxt->sax->warning = warning;
323 if (URL != NULL)
324 warning(ctxt, "failed to load external entity \"%s\"\n", URL);
325 else if (ID != NULL)
326 warning(ctxt, "failed to load external entity \"%s\"\n", ID);
327 }
328 return(NULL);
329}
330/************************************************************************
Daniel Veillard87076042004-05-03 22:54:49 +0000331 * *
332 * Memory allocation consumption debugging *
333 * *
334 ************************************************************************/
335
Daniel Veillard3af3b592004-05-05 19:22:30 +0000336static void
337OOM(void)
338{
Daniel Veillard87076042004-05-03 22:54:49 +0000339 fprintf(stderr, "Ran out of memory needs > %d bytes\n", maxmem);
William M. Brack8304d872004-06-08 13:29:32 +0000340 progresult = XMLLINT_ERR_MEM;
Daniel Veillard87076042004-05-03 22:54:49 +0000341}
342
Daniel Veillard3af3b592004-05-05 19:22:30 +0000343static void
344myFreeFunc(void *mem)
345{
Daniel Veillard87076042004-05-03 22:54:49 +0000346 xmlMemFree(mem);
347}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000348static void *
349myMallocFunc(size_t size)
350{
Daniel Veillard87076042004-05-03 22:54:49 +0000351 void *ret;
352
353 ret = xmlMemMalloc(size);
354 if (ret != NULL) {
355 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000356 OOM();
357 xmlMemFree(ret);
358 return (NULL);
359 }
Daniel Veillard87076042004-05-03 22:54:49 +0000360 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000361 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000362}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000363static void *
364myReallocFunc(void *mem, size_t size)
365{
Daniel Veillard87076042004-05-03 22:54:49 +0000366 void *ret;
367
368 ret = xmlMemRealloc(mem, size);
369 if (ret != NULL) {
370 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000371 OOM();
372 xmlMemFree(ret);
373 return (NULL);
374 }
Daniel Veillard87076042004-05-03 22:54:49 +0000375 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000376 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000377}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000378static char *
379myStrdupFunc(const char *str)
380{
Daniel Veillard87076042004-05-03 22:54:49 +0000381 char *ret;
382
383 ret = xmlMemoryStrdup(str);
384 if (ret != NULL) {
385 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000386 OOM();
387 xmlFree(ret);
388 return (NULL);
389 }
Daniel Veillard87076042004-05-03 22:54:49 +0000390 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000391 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000392}
Daniel Veillard87076042004-05-03 22:54:49 +0000393/************************************************************************
394 * *
395 * Internal timing routines to remove the necessity to have *
396 * unix-specific function calls. *
397 * *
398 ************************************************************************/
Daniel Veillard01db67c2001-12-18 07:09:59 +0000399
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000400#ifndef HAVE_GETTIMEOFDAY
401#ifdef HAVE_SYS_TIMEB_H
402#ifdef HAVE_SYS_TIME_H
403#ifdef HAVE_FTIME
404
Daniel Veillard01c13b52002-12-10 15:19:08 +0000405static int
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000406my_gettimeofday(struct timeval *tvp, void *tzp)
407{
408 struct timeb timebuffer;
409
410 ftime(&timebuffer);
411 if (tvp) {
412 tvp->tv_sec = timebuffer.time;
413 tvp->tv_usec = timebuffer.millitm * 1000L;
414 }
415 return (0);
416}
417#define HAVE_GETTIMEOFDAY 1
418#define gettimeofday my_gettimeofday
419
420#endif /* HAVE_FTIME */
421#endif /* HAVE_SYS_TIME_H */
422#endif /* HAVE_SYS_TIMEB_H */
423#endif /* !HAVE_GETTIMEOFDAY */
424
Daniel Veillard01db67c2001-12-18 07:09:59 +0000425#if defined(HAVE_GETTIMEOFDAY)
426static struct timeval begin, end;
427
428/*
429 * startTimer: call where you want to start timing
430 */
431static void
432startTimer(void)
433{
434 gettimeofday(&begin, NULL);
435}
436
437/*
438 * endTimer: call where you want to stop timing and to print out a
439 * message about the timing performed; format is a printf
440 * type argument
441 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000442static void XMLCDECL
Daniel Veillard118aed72002-09-24 14:13:13 +0000443endTimer(const char *fmt, ...)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000444{
445 long msec;
446 va_list ap;
447
448 gettimeofday(&end, NULL);
449 msec = end.tv_sec - begin.tv_sec;
450 msec *= 1000;
451 msec += (end.tv_usec - begin.tv_usec) / 1000;
452
453#ifndef HAVE_STDARG_H
454#error "endTimer required stdarg functions"
455#endif
Daniel Veillard118aed72002-09-24 14:13:13 +0000456 va_start(ap, fmt);
457 vfprintf(stderr, fmt, ap);
Daniel Veillard01db67c2001-12-18 07:09:59 +0000458 va_end(ap);
459
460 fprintf(stderr, " took %ld ms\n", msec);
461}
462#elif defined(HAVE_TIME_H)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000463/*
464 * No gettimeofday function, so we have to make do with calling clock.
465 * This is obviously less accurate, but there's little we can do about
466 * that.
467 */
Daniel Veillard90bc3712002-03-07 15:12:58 +0000468#ifndef CLOCKS_PER_SEC
469#define CLOCKS_PER_SEC 100
470#endif
Daniel Veillard01db67c2001-12-18 07:09:59 +0000471
472static clock_t begin, end;
473static void
474startTimer(void)
475{
476 begin = clock();
477}
Daniel Veillardffa3c742005-07-21 13:24:09 +0000478static void XMLCDECL
Daniel Veillard01db67c2001-12-18 07:09:59 +0000479endTimer(const char *fmt, ...)
480{
481 long msec;
482 va_list ap;
483
484 end = clock();
485 msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
486
487#ifndef HAVE_STDARG_H
488#error "endTimer required stdarg functions"
489#endif
490 va_start(ap, fmt);
491 vfprintf(stderr, fmt, ap);
492 va_end(ap);
493 fprintf(stderr, " took %ld ms\n", msec);
494}
495#else
496
497/*
498 * We don't have a gettimeofday or time.h, so we just don't do timing
499 */
500static void
501startTimer(void)
502{
503 /*
504 * Do nothing
505 */
506}
Daniel Veillardffa3c742005-07-21 13:24:09 +0000507static void XMLCDECL
Daniel Veillard01db67c2001-12-18 07:09:59 +0000508endTimer(char *format, ...)
509{
510 /*
511 * We cannot do anything because we don't have a timing function
512 */
513#ifdef HAVE_STDARG_H
514 va_start(ap, format);
515 vfprintf(stderr, format, ap);
516 va_end(ap);
517 fprintf(stderr, " was not timed\n", msec);
518#else
519 /* We don't have gettimeofday, time or stdarg.h, what crazy world is
520 * this ?!
521 */
522#endif
523}
524#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000525/************************************************************************
526 * *
527 * HTML ouput *
528 * *
529 ************************************************************************/
Daniel Veillard24505b02005-07-28 23:49:35 +0000530static char buffer[50000];
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000531
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000532static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000533xmlHTMLEncodeSend(void) {
534 char *result;
535
536 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
537 if (result) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000538 xmlGenericError(xmlGenericErrorContext, "%s", result);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000539 xmlFree(result);
540 }
541 buffer[0] = 0;
542}
543
544/**
545 * xmlHTMLPrintFileInfo:
546 * @input: an xmlParserInputPtr input
547 *
548 * Displays the associated file and line informations for the current input
549 */
550
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000551static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000552xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000553 int len;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000554 xmlGenericError(xmlGenericErrorContext, "<p>");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000555
556 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000557 if (input != NULL) {
558 if (input->filename) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000559 snprintf(&buffer[len], sizeof(buffer) - len, "%s:%d: ", input->filename,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000560 input->line);
561 } else {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000562 snprintf(&buffer[len], sizeof(buffer) - len, "Entity: line %d: ", input->line);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000563 }
564 }
565 xmlHTMLEncodeSend();
566}
567
568/**
569 * xmlHTMLPrintFileContext:
570 * @input: an xmlParserInputPtr input
571 *
572 * Displays current context within the input content for error tracking
573 */
574
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000575static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000576xmlHTMLPrintFileContext(xmlParserInputPtr input) {
577 const xmlChar *cur, *base;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000578 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000579 int n;
580
581 if (input == NULL) return;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000582 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000583 cur = input->cur;
584 base = input->base;
585 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
586 cur--;
587 }
588 n = 0;
589 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
590 cur--;
591 if ((*cur == '\n') || (*cur == '\r')) cur++;
592 base = cur;
593 n = 0;
594 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000595 len = strlen(buffer);
596 snprintf(&buffer[len], sizeof(buffer) - len, "%c",
597 (unsigned char) *cur++);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000598 n++;
599 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000600 len = strlen(buffer);
601 snprintf(&buffer[len], sizeof(buffer) - len, "\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000602 cur = input->cur;
603 while ((*cur == '\n') || (*cur == '\r'))
604 cur--;
605 n = 0;
606 while ((cur != base) && (n++ < 80)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000607 len = strlen(buffer);
608 snprintf(&buffer[len], sizeof(buffer) - len, " ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000609 base++;
610 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000611 len = strlen(buffer);
612 snprintf(&buffer[len], sizeof(buffer) - len, "^\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000613 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000614 xmlGenericError(xmlGenericErrorContext, "</pre>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000615}
616
617/**
618 * xmlHTMLError:
619 * @ctx: an XML parser context
620 * @msg: the message to display/transmit
621 * @...: extra parameters for the message display
622 *
623 * Display and format an error messages, gives file, line, position and
624 * extra parameters.
625 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000626static void XMLCDECL
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000627xmlHTMLError(void *ctx, const char *msg, ...)
628{
629 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
630 xmlParserInputPtr input;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000631 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000632 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000633
634 buffer[0] = 0;
635 input = ctxt->input;
636 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000637 input = ctxt->inputTab[ctxt->inputNr - 2];
638 }
639
640 xmlHTMLPrintFileInfo(input);
641
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000642 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000643 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000644 len = strlen(buffer);
645 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000646 va_end(args);
647 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000648 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000649
650 xmlHTMLPrintFileContext(input);
651 xmlHTMLEncodeSend();
652}
653
654/**
655 * xmlHTMLWarning:
656 * @ctx: an XML parser context
657 * @msg: the message to display/transmit
658 * @...: extra parameters for the message display
659 *
660 * Display and format a warning messages, gives file, line, position and
661 * extra parameters.
662 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000663static void XMLCDECL
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000664xmlHTMLWarning(void *ctx, const char *msg, ...)
665{
666 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
667 xmlParserInputPtr input;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000668 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000669 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000670
671 buffer[0] = 0;
672 input = ctxt->input;
673 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000674 input = ctxt->inputTab[ctxt->inputNr - 2];
675 }
676
677
678 xmlHTMLPrintFileInfo(input);
679
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000680 xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000681 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000682 len = strlen(buffer);
683 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000684 va_end(args);
685 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000686 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000687
688 xmlHTMLPrintFileContext(input);
689 xmlHTMLEncodeSend();
690}
691
692/**
693 * xmlHTMLValidityError:
694 * @ctx: an XML parser context
695 * @msg: the message to display/transmit
696 * @...: extra parameters for the message display
697 *
698 * Display and format an validity error messages, gives file,
699 * line, position and extra parameters.
700 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000701static void XMLCDECL
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000702xmlHTMLValidityError(void *ctx, const char *msg, ...)
703{
704 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
705 xmlParserInputPtr input;
706 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000707 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000708
709 buffer[0] = 0;
710 input = ctxt->input;
711 if ((input->filename == NULL) && (ctxt->inputNr > 1))
712 input = ctxt->inputTab[ctxt->inputNr - 2];
713
714 xmlHTMLPrintFileInfo(input);
715
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000716 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000717 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000718 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000719 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000720 va_end(args);
721 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000722 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000723
724 xmlHTMLPrintFileContext(input);
725 xmlHTMLEncodeSend();
Daniel Veillard9fcb4912005-03-16 12:57:31 +0000726 progresult = XMLLINT_ERR_VALID;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000727}
728
729/**
730 * xmlHTMLValidityWarning:
731 * @ctx: an XML parser context
732 * @msg: the message to display/transmit
733 * @...: extra parameters for the message display
734 *
735 * Display and format a validity warning messages, gives file, line,
736 * position and extra parameters.
737 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000738static void XMLCDECL
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000739xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
740{
741 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
742 xmlParserInputPtr input;
743 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000744 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000745
746 buffer[0] = 0;
747 input = ctxt->input;
748 if ((input->filename == NULL) && (ctxt->inputNr > 1))
749 input = ctxt->inputTab[ctxt->inputNr - 2];
750
751 xmlHTMLPrintFileInfo(input);
752
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000753 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000754 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000755 len = strlen(buffer);
756 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000757 va_end(args);
758 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000759 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000760
761 xmlHTMLPrintFileContext(input);
762 xmlHTMLEncodeSend();
763}
764
765/************************************************************************
766 * *
767 * Shell Interface *
768 * *
769 ************************************************************************/
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000770#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000771#ifdef LIBXML_XPATH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000772/**
773 * xmlShellReadline:
774 * @prompt: the prompt value
775 *
776 * Read a string
777 *
778 * Returns a pointer to it or NULL on EOF the caller is expected to
779 * free the returned string.
780 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000781static char *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000782xmlShellReadline(char *prompt) {
783#ifdef HAVE_LIBREADLINE
784 char *line_read;
785
786 /* Get a line from the user. */
787 line_read = readline (prompt);
788
789 /* If the line has any text in it, save it on the history. */
790 if (line_read && *line_read)
791 add_history (line_read);
792
793 return (line_read);
794#else
795 char line_read[501];
Daniel Veillard29e43992001-12-13 22:21:58 +0000796 char *ret;
797 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000798
799 if (prompt != NULL)
800 fprintf(stdout, "%s", prompt);
801 if (!fgets(line_read, 500, stdin))
802 return(NULL);
803 line_read[500] = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000804 len = strlen(line_read);
805 ret = (char *) malloc(len + 1);
806 if (ret != NULL) {
807 memcpy (ret, line_read, len + 1);
808 }
809 return(ret);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000810#endif
811}
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000812#endif /* LIBXML_XPATH_ENABLED */
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000813#endif /* LIBXML_DEBUG_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000814
815/************************************************************************
816 * *
Daniel Veillard5e873c42000-04-12 13:27:38 +0000817 * I/O Interfaces *
818 * *
819 ************************************************************************/
820
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000821static int myRead(FILE *f, char * buf, int len) {
822 return(fread(buf, 1, len, f));
Daniel Veillard5e873c42000-04-12 13:27:38 +0000823}
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000824static void myClose(FILE *f) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000825 if (f != stdin) {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000826 fclose(f);
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000827 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000828}
829
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000830/************************************************************************
831 * *
832 * SAX based tests *
833 * *
834 ************************************************************************/
835
836/*
837 * empty SAX block
838 */
Daniel Veillard24505b02005-07-28 23:49:35 +0000839static xmlSAXHandler emptySAXHandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000840 NULL, /* internalSubset */
841 NULL, /* isStandalone */
842 NULL, /* hasInternalSubset */
843 NULL, /* hasExternalSubset */
844 NULL, /* resolveEntity */
845 NULL, /* getEntity */
846 NULL, /* entityDecl */
847 NULL, /* notationDecl */
848 NULL, /* attributeDecl */
849 NULL, /* elementDecl */
850 NULL, /* unparsedEntityDecl */
851 NULL, /* setDocumentLocator */
852 NULL, /* startDocument */
853 NULL, /* endDocument */
854 NULL, /* startElement */
855 NULL, /* endElement */
856 NULL, /* reference */
857 NULL, /* characters */
858 NULL, /* ignorableWhitespace */
859 NULL, /* processingInstruction */
860 NULL, /* comment */
861 NULL, /* xmlParserWarning */
862 NULL, /* xmlParserError */
863 NULL, /* xmlParserError */
864 NULL, /* getParameterEntity */
865 NULL, /* cdataBlock; */
866 NULL, /* externalSubset; */
Daniel Veillard971771e2005-07-09 17:32:57 +0000867 XML_SAX2_MAGIC,
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000868 NULL,
869 NULL, /* startElementNs */
870 NULL, /* endElementNs */
871 NULL /* xmlStructuredErrorFunc */
872};
873
Daniel Veillard24505b02005-07-28 23:49:35 +0000874static xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000875extern xmlSAXHandlerPtr debugSAXHandler;
876static int callbacks;
877
878/**
879 * isStandaloneDebug:
880 * @ctxt: An XML parser context
881 *
882 * Is this document tagged standalone ?
883 *
884 * Returns 1 if true
885 */
886static int
887isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
888{
889 callbacks++;
890 if (noout)
891 return(0);
892 fprintf(stdout, "SAX.isStandalone()\n");
893 return(0);
894}
895
896/**
897 * hasInternalSubsetDebug:
898 * @ctxt: An XML parser context
899 *
900 * Does this document has an internal subset
901 *
902 * Returns 1 if true
903 */
904static int
905hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
906{
907 callbacks++;
908 if (noout)
909 return(0);
910 fprintf(stdout, "SAX.hasInternalSubset()\n");
911 return(0);
912}
913
914/**
915 * hasExternalSubsetDebug:
916 * @ctxt: An XML parser context
917 *
918 * Does this document has an external subset
919 *
920 * Returns 1 if true
921 */
922static int
923hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
924{
925 callbacks++;
926 if (noout)
927 return(0);
928 fprintf(stdout, "SAX.hasExternalSubset()\n");
929 return(0);
930}
931
932/**
933 * internalSubsetDebug:
934 * @ctxt: An XML parser context
935 *
936 * Does this document has an internal subset
937 */
938static void
939internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
940 const xmlChar *ExternalID, const xmlChar *SystemID)
941{
942 callbacks++;
943 if (noout)
944 return;
945 fprintf(stdout, "SAX.internalSubset(%s,", name);
946 if (ExternalID == NULL)
947 fprintf(stdout, " ,");
948 else
949 fprintf(stdout, " %s,", ExternalID);
950 if (SystemID == NULL)
951 fprintf(stdout, " )\n");
952 else
953 fprintf(stdout, " %s)\n", SystemID);
954}
955
956/**
957 * externalSubsetDebug:
958 * @ctxt: An XML parser context
959 *
960 * Does this document has an external subset
961 */
962static void
963externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
964 const xmlChar *ExternalID, const xmlChar *SystemID)
965{
966 callbacks++;
967 if (noout)
968 return;
969 fprintf(stdout, "SAX.externalSubset(%s,", name);
970 if (ExternalID == NULL)
971 fprintf(stdout, " ,");
972 else
973 fprintf(stdout, " %s,", ExternalID);
974 if (SystemID == NULL)
975 fprintf(stdout, " )\n");
976 else
977 fprintf(stdout, " %s)\n", SystemID);
978}
979
980/**
981 * resolveEntityDebug:
982 * @ctxt: An XML parser context
983 * @publicId: The public ID of the entity
984 * @systemId: The system ID of the entity
985 *
986 * Special entity resolver, better left to the parser, it has
987 * more context than the application layer.
988 * The default behaviour is to NOT resolve the entities, in that case
989 * the ENTITY_REF nodes are built in the structure (and the parameter
990 * values).
991 *
992 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
993 */
994static xmlParserInputPtr
995resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
996{
997 callbacks++;
998 if (noout)
999 return(NULL);
1000 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1001
1002
1003 fprintf(stdout, "SAX.resolveEntity(");
1004 if (publicId != NULL)
1005 fprintf(stdout, "%s", (char *)publicId);
1006 else
1007 fprintf(stdout, " ");
1008 if (systemId != NULL)
1009 fprintf(stdout, ", %s)\n", (char *)systemId);
1010 else
1011 fprintf(stdout, ", )\n");
1012 return(NULL);
1013}
1014
1015/**
1016 * getEntityDebug:
1017 * @ctxt: An XML parser context
1018 * @name: The entity name
1019 *
1020 * Get an entity by name
1021 *
1022 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
1023 */
1024static xmlEntityPtr
1025getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1026{
1027 callbacks++;
1028 if (noout)
1029 return(NULL);
1030 fprintf(stdout, "SAX.getEntity(%s)\n", name);
1031 return(NULL);
1032}
1033
1034/**
1035 * getParameterEntityDebug:
1036 * @ctxt: An XML parser context
1037 * @name: The entity name
1038 *
1039 * Get a parameter entity by name
1040 *
1041 * Returns the xmlParserInputPtr
1042 */
1043static xmlEntityPtr
1044getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1045{
1046 callbacks++;
1047 if (noout)
1048 return(NULL);
1049 fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
1050 return(NULL);
1051}
1052
1053
1054/**
1055 * entityDeclDebug:
1056 * @ctxt: An XML parser context
1057 * @name: the entity name
1058 * @type: the entity type
1059 * @publicId: The public ID of the entity
1060 * @systemId: The system ID of the entity
1061 * @content: the entity value (without processing).
1062 *
1063 * An entity definition has been parsed
1064 */
1065static void
1066entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
1067 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
1068{
1069const xmlChar *nullstr = BAD_CAST "(null)";
1070 /* not all libraries handle printing null pointers nicely */
1071 if (publicId == NULL)
1072 publicId = nullstr;
1073 if (systemId == NULL)
1074 systemId = nullstr;
1075 if (content == NULL)
1076 content = (xmlChar *)nullstr;
1077 callbacks++;
1078 if (noout)
1079 return;
1080 fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
1081 name, type, publicId, systemId, content);
1082}
1083
1084/**
1085 * attributeDeclDebug:
1086 * @ctxt: An XML parser context
1087 * @name: the attribute name
1088 * @type: the attribute type
1089 *
1090 * An attribute definition has been parsed
1091 */
1092static void
1093attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar * elem,
1094 const xmlChar * name, int type, int def,
1095 const xmlChar * defaultValue, xmlEnumerationPtr tree)
1096{
1097 callbacks++;
1098 if (noout)
1099 return;
1100 if (defaultValue == NULL)
1101 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
1102 elem, name, type, def);
1103 else
1104 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
1105 elem, name, type, def, defaultValue);
1106 xmlFreeEnumeration(tree);
1107}
1108
1109/**
1110 * elementDeclDebug:
1111 * @ctxt: An XML parser context
1112 * @name: the element name
1113 * @type: the element type
1114 * @content: the element value (without processing).
1115 *
1116 * An element definition has been parsed
1117 */
1118static void
1119elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
1120 xmlElementContentPtr content ATTRIBUTE_UNUSED)
1121{
1122 callbacks++;
1123 if (noout)
1124 return;
1125 fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
1126 name, type);
1127}
1128
1129/**
1130 * notationDeclDebug:
1131 * @ctxt: An XML parser context
1132 * @name: The name of the notation
1133 * @publicId: The public ID of the entity
1134 * @systemId: The system ID of the entity
1135 *
1136 * What to do when a notation declaration has been parsed.
1137 */
1138static void
1139notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
1140 const xmlChar *publicId, const xmlChar *systemId)
1141{
1142 callbacks++;
1143 if (noout)
1144 return;
1145 fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
1146 (char *) name, (char *) publicId, (char *) systemId);
1147}
1148
1149/**
1150 * unparsedEntityDeclDebug:
1151 * @ctxt: An XML parser context
1152 * @name: The name of the entity
1153 * @publicId: The public ID of the entity
1154 * @systemId: The system ID of the entity
1155 * @notationName: the name of the notation
1156 *
1157 * What to do when an unparsed entity declaration is parsed
1158 */
1159static void
1160unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
1161 const xmlChar *publicId, const xmlChar *systemId,
1162 const xmlChar *notationName)
1163{
1164const xmlChar *nullstr = BAD_CAST "(null)";
1165
1166 if (publicId == NULL)
1167 publicId = nullstr;
1168 if (systemId == NULL)
1169 systemId = nullstr;
1170 if (notationName == NULL)
1171 notationName = nullstr;
1172 callbacks++;
1173 if (noout)
1174 return;
1175 fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
1176 (char *) name, (char *) publicId, (char *) systemId,
1177 (char *) notationName);
1178}
1179
1180/**
1181 * setDocumentLocatorDebug:
1182 * @ctxt: An XML parser context
1183 * @loc: A SAX Locator
1184 *
1185 * Receive the document locator at startup, actually xmlDefaultSAXLocator
1186 * Everything is available on the context, so this is useless in our case.
1187 */
1188static void
1189setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
1190{
1191 callbacks++;
1192 if (noout)
1193 return;
1194 fprintf(stdout, "SAX.setDocumentLocator()\n");
1195}
1196
1197/**
1198 * startDocumentDebug:
1199 * @ctxt: An XML parser context
1200 *
1201 * called when the document start being processed.
1202 */
1203static void
1204startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
1205{
1206 callbacks++;
1207 if (noout)
1208 return;
1209 fprintf(stdout, "SAX.startDocument()\n");
1210}
1211
1212/**
1213 * endDocumentDebug:
1214 * @ctxt: An XML parser context
1215 *
1216 * called when the document end has been detected.
1217 */
1218static void
1219endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
1220{
1221 callbacks++;
1222 if (noout)
1223 return;
1224 fprintf(stdout, "SAX.endDocument()\n");
1225}
1226
1227/**
1228 * startElementDebug:
1229 * @ctxt: An XML parser context
1230 * @name: The element name
1231 *
1232 * called when an opening tag has been processed.
1233 */
1234static void
1235startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
1236{
1237 int i;
1238
1239 callbacks++;
1240 if (noout)
1241 return;
1242 fprintf(stdout, "SAX.startElement(%s", (char *) name);
1243 if (atts != NULL) {
1244 for (i = 0;(atts[i] != NULL);i++) {
1245 fprintf(stdout, ", %s='", atts[i++]);
1246 if (atts[i] != NULL)
1247 fprintf(stdout, "%s'", atts[i]);
1248 }
1249 }
1250 fprintf(stdout, ")\n");
1251}
1252
1253/**
1254 * endElementDebug:
1255 * @ctxt: An XML parser context
1256 * @name: The element name
1257 *
1258 * called when the end of an element has been detected.
1259 */
1260static void
1261endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1262{
1263 callbacks++;
1264 if (noout)
1265 return;
1266 fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
1267}
1268
1269/**
1270 * charactersDebug:
1271 * @ctxt: An XML parser context
1272 * @ch: a xmlChar string
1273 * @len: the number of xmlChar
1274 *
1275 * receiving some chars from the parser.
1276 * Question: how much at a time ???
1277 */
1278static void
1279charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
1280{
1281 char out[40];
1282 int i;
1283
1284 callbacks++;
1285 if (noout)
1286 return;
1287 for (i = 0;(i<len) && (i < 30);i++)
1288 out[i] = ch[i];
1289 out[i] = 0;
1290
1291 fprintf(stdout, "SAX.characters(%s, %d)\n", out, len);
1292}
1293
1294/**
1295 * referenceDebug:
1296 * @ctxt: An XML parser context
1297 * @name: The entity name
1298 *
1299 * called when an entity reference is detected.
1300 */
1301static void
1302referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1303{
1304 callbacks++;
1305 if (noout)
1306 return;
1307 fprintf(stdout, "SAX.reference(%s)\n", name);
1308}
1309
1310/**
1311 * ignorableWhitespaceDebug:
1312 * @ctxt: An XML parser context
1313 * @ch: a xmlChar string
1314 * @start: the first char in the string
1315 * @len: the number of xmlChar
1316 *
1317 * receiving some ignorable whitespaces from the parser.
1318 * Question: how much at a time ???
1319 */
1320static void
1321ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
1322{
1323 char out[40];
1324 int i;
1325
1326 callbacks++;
1327 if (noout)
1328 return;
1329 for (i = 0;(i<len) && (i < 30);i++)
1330 out[i] = ch[i];
1331 out[i] = 0;
1332 fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", out, len);
1333}
1334
1335/**
1336 * processingInstructionDebug:
1337 * @ctxt: An XML parser context
1338 * @target: the target name
1339 * @data: the PI data's
1340 * @len: the number of xmlChar
1341 *
1342 * A processing instruction has been parsed.
1343 */
1344static void
1345processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
1346 const xmlChar *data)
1347{
1348 callbacks++;
1349 if (noout)
1350 return;
1351 if (data != NULL)
1352 fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
1353 (char *) target, (char *) data);
1354 else
1355 fprintf(stdout, "SAX.processingInstruction(%s, NULL)\n",
1356 (char *) target);
1357}
1358
1359/**
1360 * cdataBlockDebug:
1361 * @ctx: the user data (XML parser context)
1362 * @value: The pcdata content
1363 * @len: the block length
1364 *
1365 * called when a pcdata block has been parsed
1366 */
1367static void
1368cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
1369{
1370 callbacks++;
1371 if (noout)
1372 return;
1373 fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
1374 (char *) value, len);
1375}
1376
1377/**
1378 * commentDebug:
1379 * @ctxt: An XML parser context
1380 * @value: the comment content
1381 *
1382 * A comment has been parsed.
1383 */
1384static void
1385commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
1386{
1387 callbacks++;
1388 if (noout)
1389 return;
1390 fprintf(stdout, "SAX.comment(%s)\n", value);
1391}
1392
1393/**
1394 * warningDebug:
1395 * @ctxt: An XML parser context
1396 * @msg: the message to display/transmit
1397 * @...: extra parameters for the message display
1398 *
1399 * Display and format a warning messages, gives file, line, position and
1400 * extra parameters.
1401 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001402static void XMLCDECL
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001403warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1404{
1405 va_list args;
1406
1407 callbacks++;
1408 if (noout)
1409 return;
1410 va_start(args, msg);
1411 fprintf(stdout, "SAX.warning: ");
1412 vfprintf(stdout, msg, args);
1413 va_end(args);
1414}
1415
1416/**
1417 * errorDebug:
1418 * @ctxt: An XML parser context
1419 * @msg: the message to display/transmit
1420 * @...: extra parameters for the message display
1421 *
1422 * Display and format a error messages, gives file, line, position and
1423 * extra parameters.
1424 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001425static void XMLCDECL
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001426errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1427{
1428 va_list args;
1429
1430 callbacks++;
1431 if (noout)
1432 return;
1433 va_start(args, msg);
1434 fprintf(stdout, "SAX.error: ");
1435 vfprintf(stdout, msg, args);
1436 va_end(args);
1437}
1438
1439/**
1440 * fatalErrorDebug:
1441 * @ctxt: An XML parser context
1442 * @msg: the message to display/transmit
1443 * @...: extra parameters for the message display
1444 *
1445 * Display and format a fatalError messages, gives file, line, position and
1446 * extra parameters.
1447 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001448static void XMLCDECL
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001449fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1450{
1451 va_list args;
1452
1453 callbacks++;
1454 if (noout)
1455 return;
1456 va_start(args, msg);
1457 fprintf(stdout, "SAX.fatalError: ");
1458 vfprintf(stdout, msg, args);
1459 va_end(args);
1460}
1461
Daniel Veillard24505b02005-07-28 23:49:35 +00001462static xmlSAXHandler debugSAXHandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001463 internalSubsetDebug,
1464 isStandaloneDebug,
1465 hasInternalSubsetDebug,
1466 hasExternalSubsetDebug,
1467 resolveEntityDebug,
1468 getEntityDebug,
1469 entityDeclDebug,
1470 notationDeclDebug,
1471 attributeDeclDebug,
1472 elementDeclDebug,
1473 unparsedEntityDeclDebug,
1474 setDocumentLocatorDebug,
1475 startDocumentDebug,
1476 endDocumentDebug,
1477 startElementDebug,
1478 endElementDebug,
1479 referenceDebug,
1480 charactersDebug,
1481 ignorableWhitespaceDebug,
1482 processingInstructionDebug,
1483 commentDebug,
1484 warningDebug,
1485 errorDebug,
1486 fatalErrorDebug,
1487 getParameterEntityDebug,
1488 cdataBlockDebug,
1489 externalSubsetDebug,
1490 1,
1491 NULL,
1492 NULL,
1493 NULL,
1494 NULL
1495};
1496
1497xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
1498
1499/*
1500 * SAX2 specific callbacks
1501 */
1502/**
1503 * startElementNsDebug:
1504 * @ctxt: An XML parser context
1505 * @name: The element name
1506 *
1507 * called when an opening tag has been processed.
1508 */
1509static void
1510startElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
1511 const xmlChar *localname,
1512 const xmlChar *prefix,
1513 const xmlChar *URI,
1514 int nb_namespaces,
1515 const xmlChar **namespaces,
1516 int nb_attributes,
1517 int nb_defaulted,
1518 const xmlChar **attributes)
1519{
1520 int i;
1521
1522 callbacks++;
1523 if (noout)
1524 return;
1525 fprintf(stdout, "SAX.startElementNs(%s", (char *) localname);
1526 if (prefix == NULL)
1527 fprintf(stdout, ", NULL");
1528 else
1529 fprintf(stdout, ", %s", (char *) prefix);
1530 if (URI == NULL)
1531 fprintf(stdout, ", NULL");
1532 else
1533 fprintf(stdout, ", '%s'", (char *) URI);
1534 fprintf(stdout, ", %d", nb_namespaces);
1535
1536 if (namespaces != NULL) {
1537 for (i = 0;i < nb_namespaces * 2;i++) {
1538 fprintf(stdout, ", xmlns");
1539 if (namespaces[i] != NULL)
1540 fprintf(stdout, ":%s", namespaces[i]);
1541 i++;
1542 fprintf(stdout, "='%s'", namespaces[i]);
1543 }
1544 }
1545 fprintf(stdout, ", %d, %d", nb_attributes, nb_defaulted);
1546 if (attributes != NULL) {
1547 for (i = 0;i < nb_attributes * 5;i += 5) {
1548 if (attributes[i + 1] != NULL)
1549 fprintf(stdout, ", %s:%s='", attributes[i + 1], attributes[i]);
1550 else
1551 fprintf(stdout, ", %s='", attributes[i]);
1552 fprintf(stdout, "%.4s...', %d", attributes[i + 3],
1553 (int)(attributes[i + 4] - attributes[i + 3]));
1554 }
1555 }
1556 fprintf(stdout, ")\n");
1557}
1558
1559/**
1560 * endElementDebug:
1561 * @ctxt: An XML parser context
1562 * @name: The element name
1563 *
1564 * called when the end of an element has been detected.
1565 */
1566static void
1567endElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
1568 const xmlChar *localname,
1569 const xmlChar *prefix,
1570 const xmlChar *URI)
1571{
1572 callbacks++;
1573 if (noout)
1574 return;
1575 fprintf(stdout, "SAX.endElementNs(%s", (char *) localname);
1576 if (prefix == NULL)
1577 fprintf(stdout, ", NULL");
1578 else
1579 fprintf(stdout, ", %s", (char *) prefix);
1580 if (URI == NULL)
1581 fprintf(stdout, ", NULL)\n");
1582 else
1583 fprintf(stdout, ", '%s')\n", (char *) URI);
1584}
1585
Daniel Veillard24505b02005-07-28 23:49:35 +00001586static xmlSAXHandler debugSAX2HandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001587 internalSubsetDebug,
1588 isStandaloneDebug,
1589 hasInternalSubsetDebug,
1590 hasExternalSubsetDebug,
1591 resolveEntityDebug,
1592 getEntityDebug,
1593 entityDeclDebug,
1594 notationDeclDebug,
1595 attributeDeclDebug,
1596 elementDeclDebug,
1597 unparsedEntityDeclDebug,
1598 setDocumentLocatorDebug,
1599 startDocumentDebug,
1600 endDocumentDebug,
1601 NULL,
1602 NULL,
1603 referenceDebug,
1604 charactersDebug,
1605 ignorableWhitespaceDebug,
1606 processingInstructionDebug,
1607 commentDebug,
1608 warningDebug,
1609 errorDebug,
1610 fatalErrorDebug,
1611 getParameterEntityDebug,
1612 cdataBlockDebug,
1613 externalSubsetDebug,
1614 XML_SAX2_MAGIC,
1615 NULL,
1616 startElementNsDebug,
1617 endElementNsDebug,
1618 NULL
1619};
1620
Daniel Veillard24505b02005-07-28 23:49:35 +00001621static xmlSAXHandlerPtr debugSAX2Handler = &debugSAX2HandlerStruct;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001622
1623static void
1624testSAX(const char *filename) {
1625 xmlSAXHandlerPtr handler;
1626 const char *user_data = "user_data"; /* mostly for debugging */
1627 xmlParserInputBufferPtr buf = NULL;
1628 xmlParserInputPtr inputStream;
1629 xmlParserCtxtPtr ctxt = NULL;
1630 xmlSAXHandlerPtr old_sax = NULL;
1631
1632 callbacks = 0;
1633
1634 if (noout) {
1635 handler = emptySAXHandler;
Daniel Veillard78dfc9f2005-07-10 22:30:30 +00001636#ifdef LIBXML_SAX1_ENABLED
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001637 } else if (sax1) {
1638 handler = debugSAXHandler;
Daniel Veillard78dfc9f2005-07-10 22:30:30 +00001639#endif
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001640 } else {
1641 handler = debugSAX2Handler;
1642 }
1643
1644 /*
1645 * it's not the simplest code but the most generic in term of I/O
1646 */
1647 buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
1648 if (buf == NULL) {
1649 goto error;
1650 }
1651
1652#ifdef LIBXML_SCHEMAS_ENABLED
1653 if (wxschemas != NULL) {
1654 int ret;
1655 xmlSchemaValidCtxtPtr vctxt;
1656
1657 vctxt = xmlSchemaNewValidCtxt(wxschemas);
1658 xmlSchemaSetValidErrors(vctxt,
1659 (xmlSchemaValidityErrorFunc) fprintf,
1660 (xmlSchemaValidityWarningFunc) fprintf,
1661 stderr);
1662
Daniel Veillard971771e2005-07-09 17:32:57 +00001663 ret = xmlSchemaValidateStream(vctxt, buf, 0, handler,
1664 (void *)user_data);
1665 if (repeat == 0) {
1666 if (ret == 0) {
1667 fprintf(stderr, "%s validates\n", filename);
1668 } else if (ret > 0) {
1669 fprintf(stderr, "%s fails to validate\n", filename);
1670 progresult = XMLLINT_ERR_VALID;
1671 } else {
1672 fprintf(stderr, "%s validation generated an internal error\n",
1673 filename);
1674 progresult = XMLLINT_ERR_VALID;
1675 }
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001676 }
1677 xmlSchemaFreeValidCtxt(vctxt);
1678 } else
1679#endif
1680 {
1681 /*
1682 * Create the parser context amd hook the input
1683 */
1684 ctxt = xmlNewParserCtxt();
1685 if (ctxt == NULL) {
1686 xmlFreeParserInputBuffer(buf);
1687 goto error;
1688 }
1689 old_sax = ctxt->sax;
1690 ctxt->sax = handler;
1691 ctxt->userData = (void *) user_data;
1692 inputStream = xmlNewIOInputStream(ctxt, buf, XML_CHAR_ENCODING_NONE);
1693 if (inputStream == NULL) {
1694 xmlFreeParserInputBuffer(buf);
1695 goto error;
1696 }
1697 inputPush(ctxt, inputStream);
1698
1699 /* do the parsing */
1700 xmlParseDocument(ctxt);
1701
1702 if (ctxt->myDoc != NULL) {
1703 fprintf(stderr, "SAX generated a doc !\n");
1704 xmlFreeDoc(ctxt->myDoc);
1705 ctxt->myDoc = NULL;
1706 }
1707 }
1708
1709error:
1710 if (ctxt != NULL) {
1711 ctxt->sax = old_sax;
1712 xmlFreeParserCtxt(ctxt);
1713 }
1714}
1715
Daniel Veillard5e873c42000-04-12 13:27:38 +00001716/************************************************************************
1717 * *
Daniel Veillard7704fb12003-01-03 16:19:51 +00001718 * Stream Test processing *
1719 * *
1720 ************************************************************************/
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001721#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00001722static void processNode(xmlTextReaderPtr reader) {
Daniel Veillard198c1bf2003-10-20 17:07:41 +00001723 const xmlChar *name, *value;
Daniel Veillard16ef8002005-01-31 00:27:50 +00001724 int type, empty;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001725
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001726 type = xmlTextReaderNodeType(reader);
Daniel Veillard16ef8002005-01-31 00:27:50 +00001727 empty = xmlTextReaderIsEmptyElement(reader);
Daniel Veillard99737f52003-03-22 14:55:50 +00001728
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001729 if (debug) {
1730 name = xmlTextReaderConstName(reader);
1731 if (name == NULL)
1732 name = BAD_CAST "--";
Daniel Veillard7704fb12003-01-03 16:19:51 +00001733
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001734 value = xmlTextReaderConstValue(reader);
1735
1736
1737 printf("%d %d %s %d %d",
1738 xmlTextReaderDepth(reader),
1739 type,
1740 name,
Daniel Veillard16ef8002005-01-31 00:27:50 +00001741 empty,
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001742 xmlTextReaderHasValue(reader));
1743 if (value == NULL)
1744 printf("\n");
1745 else {
1746 printf(" %s\n", value);
1747 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001748 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001749#ifdef LIBXML_PATTERN_ENABLED
1750 if (patternc) {
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001751 xmlChar *path = NULL;
1752 int match = -1;
1753
1754 if (type == XML_READER_TYPE_ELEMENT) {
1755 /* do the check only on element start */
1756 match = xmlPatternMatch(patternc, xmlTextReaderCurrentNode(reader));
1757
1758 if (match) {
1759 path = xmlGetNodePath(xmlTextReaderCurrentNode(reader));
1760 printf("Node %s matches pattern %s\n", path, pattern);
1761 }
1762 }
1763 if (patstream != NULL) {
1764 int ret;
1765
1766 if (type == XML_READER_TYPE_ELEMENT) {
1767 ret = xmlStreamPush(patstream,
1768 xmlTextReaderConstLocalName(reader),
1769 xmlTextReaderConstNamespaceUri(reader));
1770 if (ret < 0) {
1771 fprintf(stderr, "xmlStreamPush() failure\n");
1772 xmlFreeStreamCtxt(patstream);
1773 patstream = NULL;
1774 } else if (ret != match) {
1775 if (path == NULL) {
1776 path = xmlGetNodePath(
1777 xmlTextReaderCurrentNode(reader));
1778 }
1779 fprintf(stderr,
1780 "xmlPatternMatch and xmlStreamPush disagree\n");
1781 fprintf(stderr,
1782 " pattern %s node %s\n",
1783 pattern, path);
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001784 }
1785
1786
Daniel Veillard16ef8002005-01-31 00:27:50 +00001787 }
1788 if ((type == XML_READER_TYPE_END_ELEMENT) ||
1789 ((type == XML_READER_TYPE_ELEMENT) && (empty))) {
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001790 ret = xmlStreamPop(patstream);
1791 if (ret < 0) {
1792 fprintf(stderr, "xmlStreamPop() failure\n");
1793 xmlFreeStreamCtxt(patstream);
1794 patstream = NULL;
1795 }
1796 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001797 }
Daniel Veillardf9d16912005-01-30 22:36:30 +00001798 if (path != NULL)
1799 xmlFree(path);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001800 }
1801#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001802}
1803
1804static void streamFile(char *filename) {
1805 xmlTextReaderPtr reader;
1806 int ret;
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001807#ifdef HAVE_SYS_MMAN_H
1808 int fd = -1;
1809 struct stat info;
1810 const char *base = NULL;
1811 xmlParserInputBufferPtr input = NULL;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001812
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001813 if (memory) {
1814 if (stat(filename, &info) < 0)
1815 return;
1816 if ((fd = open(filename, O_RDONLY)) < 0)
1817 return;
1818 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
1819 if (base == (void *) MAP_FAILED)
1820 return;
1821
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001822 reader = xmlReaderForMemory(base, info.st_size, filename,
1823 NULL, options);
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001824 } else
1825#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001826 reader = xmlReaderForFile(filename, NULL, options);
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001827#ifdef LIBXML_PATTERN_ENABLED
Daniel Veillardd4301ab2005-02-03 22:24:10 +00001828 if (pattern != NULL) {
1829 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
1830 if (patternc == NULL) {
1831 xmlGenericError(xmlGenericErrorContext,
1832 "Pattern %s failed to compile\n", pattern);
1833 progresult = XMLLINT_ERR_SCHEMAPAT;
1834 pattern = NULL;
1835 }
1836 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001837 if (patternc != NULL) {
1838 patstream = xmlPatternGetStreamCtxt(patternc);
1839 if (patstream != NULL) {
1840 ret = xmlStreamPush(patstream, NULL, NULL);
1841 if (ret < 0) {
1842 fprintf(stderr, "xmlStreamPush() failure\n");
1843 xmlFreeStreamCtxt(patstream);
1844 patstream = NULL;
1845 }
1846 }
1847 }
1848#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001849
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001850
Daniel Veillard7704fb12003-01-03 16:19:51 +00001851 if (reader != NULL) {
Daniel Veillard4432df22003-09-28 18:58:27 +00001852#ifdef LIBXML_VALID_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00001853 if (valid)
1854 xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
Daniel Veillardce192eb2003-04-16 15:58:05 +00001855 else
Daniel Veillard4432df22003-09-28 18:58:27 +00001856#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardce192eb2003-04-16 15:58:05 +00001857 xmlTextReaderSetParserProp(reader, XML_PARSER_LOADDTD, 1);
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001858#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +00001859 if (relaxng != NULL) {
Daniel Veillard81514ba2003-09-16 23:17:26 +00001860 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001861 startTimer();
1862 }
1863 ret = xmlTextReaderRelaxNGValidate(reader, relaxng);
1864 if (ret < 0) {
1865 xmlGenericError(xmlGenericErrorContext,
1866 "Relax-NG schema %s failed to compile\n", relaxng);
William M. Brack8304d872004-06-08 13:29:32 +00001867 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillardce192eb2003-04-16 15:58:05 +00001868 relaxng = NULL;
1869 }
Daniel Veillard81514ba2003-09-16 23:17:26 +00001870 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001871 endTimer("Compiling the schemas");
1872 }
1873 }
Daniel Veillardf10ae122005-07-10 19:03:16 +00001874 if (schema != NULL) {
1875 if ((timing) && (!repeat)) {
1876 startTimer();
1877 }
1878 ret = xmlTextReaderSchemaValidate(reader, schema);
1879 if (ret < 0) {
1880 xmlGenericError(xmlGenericErrorContext,
1881 "XSD schema %s failed to compile\n", schema);
1882 progresult = XMLLINT_ERR_SCHEMACOMP;
1883 schema = NULL;
1884 }
1885 if ((timing) && (!repeat)) {
1886 endTimer("Compiling the schemas");
1887 }
1888 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001889#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001890
1891 /*
1892 * Process all nodes in sequence
1893 */
Daniel Veillard81514ba2003-09-16 23:17:26 +00001894 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001895 startTimer();
1896 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001897 ret = xmlTextReaderRead(reader);
1898 while (ret == 1) {
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001899 if ((debug)
1900#ifdef LIBXML_PATTERN_ENABLED
1901 || (patternc)
1902#endif
1903 )
Daniel Veillard7704fb12003-01-03 16:19:51 +00001904 processNode(reader);
1905 ret = xmlTextReaderRead(reader);
1906 }
Daniel Veillard81514ba2003-09-16 23:17:26 +00001907 if ((timing) && (!repeat)) {
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001908#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf54cd532004-02-25 11:52:31 +00001909 if (relaxng != NULL)
Daniel Veillard49138f12004-02-19 12:58:36 +00001910 endTimer("Parsing and validating");
1911 else
Daniel Veillardf54cd532004-02-25 11:52:31 +00001912#endif
Daniel Veillard4432df22003-09-28 18:58:27 +00001913#ifdef LIBXML_VALID_ENABLED
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001914 if (valid)
Daniel Veillardce192eb2003-04-16 15:58:05 +00001915 endTimer("Parsing and validating");
1916 else
Daniel Veillard4432df22003-09-28 18:58:27 +00001917#endif
Daniel Veillardf54cd532004-02-25 11:52:31 +00001918 endTimer("Parsing");
Daniel Veillardce192eb2003-04-16 15:58:05 +00001919 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001920
Daniel Veillard4432df22003-09-28 18:58:27 +00001921#ifdef LIBXML_VALID_ENABLED
Daniel Veillardf6bad792003-04-11 19:38:54 +00001922 if (valid) {
1923 if (xmlTextReaderIsValid(reader) != 1) {
1924 xmlGenericError(xmlGenericErrorContext,
1925 "Document %s does not validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001926 progresult = XMLLINT_ERR_VALID;
Daniel Veillardf6bad792003-04-11 19:38:54 +00001927 }
1928 }
Daniel Veillard4432df22003-09-28 18:58:27 +00001929#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001930#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf10ae122005-07-10 19:03:16 +00001931 if ((relaxng != NULL) || (schema != NULL)) {
Daniel Veillardf4e55762003-04-15 23:32:22 +00001932 if (xmlTextReaderIsValid(reader) != 1) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001933 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001934 progresult = XMLLINT_ERR_VALID;
Daniel Veillardf4e55762003-04-15 23:32:22 +00001935 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001936 fprintf(stderr, "%s validates\n", filename);
Daniel Veillardf4e55762003-04-15 23:32:22 +00001937 }
1938 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001939#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001940 /*
1941 * Done, cleanup and status
1942 */
1943 xmlFreeTextReader(reader);
1944 if (ret != 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001945 fprintf(stderr, "%s : failed to parse\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001946 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001947 }
1948 } else {
1949 fprintf(stderr, "Unable to open %s\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001950 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001951 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001952#ifdef LIBXML_PATTERN_ENABLED
1953 if (patstream != NULL) {
1954 xmlFreeStreamCtxt(patstream);
1955 patstream = NULL;
1956 }
1957#endif
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001958#ifdef HAVE_SYS_MMAN_H
1959 if (memory) {
1960 xmlFreeParserInputBuffer(input);
1961 munmap((char *) base, info.st_size);
1962 close(fd);
1963 }
1964#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001965}
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001966
1967static void walkDoc(xmlDocPtr doc) {
1968 xmlTextReaderPtr reader;
1969 int ret;
1970
Daniel Veillardd4301ab2005-02-03 22:24:10 +00001971#ifdef LIBXML_PATTERN_ENABLED
1972 xmlNodePtr root;
1973 const xmlChar *namespaces[22];
1974 int i;
1975 xmlNsPtr ns;
1976
1977 root = xmlDocGetRootElement(doc);
1978 for (ns = root->nsDef, i = 0;ns != NULL && i < 20;ns=ns->next) {
1979 namespaces[i++] = ns->href;
1980 namespaces[i++] = ns->prefix;
1981 }
1982 namespaces[i++] = NULL;
1983 namespaces[i++] = NULL;
1984
1985 if (pattern != NULL) {
1986 patternc = xmlPatterncompile((const xmlChar *) pattern, doc->dict,
1987 0, &namespaces[0]);
1988 if (patternc == NULL) {
1989 xmlGenericError(xmlGenericErrorContext,
1990 "Pattern %s failed to compile\n", pattern);
1991 progresult = XMLLINT_ERR_SCHEMAPAT;
1992 pattern = NULL;
1993 }
1994 }
Daniel Veillard2b2e02d2005-02-05 23:20:22 +00001995 if (patternc != NULL) {
1996 patstream = xmlPatternGetStreamCtxt(patternc);
1997 if (patstream != NULL) {
1998 ret = xmlStreamPush(patstream, NULL, NULL);
1999 if (ret < 0) {
2000 fprintf(stderr, "xmlStreamPush() failure\n");
2001 xmlFreeStreamCtxt(patstream);
2002 patstream = NULL;
2003 }
2004 }
2005 }
Daniel Veillardd4301ab2005-02-03 22:24:10 +00002006#endif /* LIBXML_PATTERN_ENABLED */
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002007 reader = xmlReaderWalker(doc);
2008 if (reader != NULL) {
2009 if ((timing) && (!repeat)) {
2010 startTimer();
2011 }
2012 ret = xmlTextReaderRead(reader);
2013 while (ret == 1) {
Daniel Veillardb3de70c2003-12-02 22:32:15 +00002014 if ((debug)
2015#ifdef LIBXML_PATTERN_ENABLED
2016 || (patternc)
2017#endif
2018 )
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002019 processNode(reader);
2020 ret = xmlTextReaderRead(reader);
2021 }
2022 if ((timing) && (!repeat)) {
2023 endTimer("walking through the doc");
2024 }
2025 xmlFreeTextReader(reader);
2026 if (ret != 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002027 fprintf(stderr, "failed to walk through the doc\n");
William M. Brack8304d872004-06-08 13:29:32 +00002028 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002029 }
2030 } else {
2031 fprintf(stderr, "Failed to crate a reader from the document\n");
William M. Brack8304d872004-06-08 13:29:32 +00002032 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002033 }
Daniel Veillard2b2e02d2005-02-05 23:20:22 +00002034#ifdef LIBXML_PATTERN_ENABLED
2035 if (patstream != NULL) {
2036 xmlFreeStreamCtxt(patstream);
2037 patstream = NULL;
2038 }
2039#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002040}
Daniel Veillard81273902003-09-30 00:43:48 +00002041#endif /* LIBXML_READER_ENABLED */
Daniel Veillard7704fb12003-01-03 16:19:51 +00002042
2043/************************************************************************
2044 * *
2045 * Tree Test processing *
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002046 * *
2047 ************************************************************************/
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002048static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
Daniel Veillard652327a2003-09-29 18:02:38 +00002049 xmlDocPtr doc = NULL;
2050#ifdef LIBXML_TREE_ENABLED
2051 xmlDocPtr tmp;
2052#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002053
Daniel Veillard48b2f892001-02-25 16:11:03 +00002054 if ((timing) && (!repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00002055 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002056
2057
Daniel Veillard652327a2003-09-29 18:02:38 +00002058#ifdef LIBXML_TREE_ENABLED
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002059 if (filename == NULL) {
2060 if (generate) {
2061 xmlNodePtr n;
2062
2063 doc = xmlNewDoc(BAD_CAST "1.0");
Daniel Veillard95ddcd32004-10-26 21:53:55 +00002064 n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002065 xmlNodeSetContent(n, BAD_CAST "abc");
2066 xmlDocSetRootElement(doc, n);
2067 }
2068 }
Daniel Veillard652327a2003-09-29 18:02:38 +00002069#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002070#ifdef LIBXML_HTML_ENABLED
Daniel Veillard73b013f2003-09-30 12:36:01 +00002071#ifdef LIBXML_PUSH_ENABLED
William M. Brack78637da2003-07-31 14:47:38 +00002072 else if ((html) && (push)) {
2073 FILE *f;
2074
William M. Brack3403add2004-06-27 02:07:51 +00002075#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2076 f = fopen(filename, "rb");
2077#else
2078 f = fopen(filename, "r");
2079#endif
William M. Brack78637da2003-07-31 14:47:38 +00002080 if (f != NULL) {
2081 int res, size = 3;
2082 char chars[4096];
2083 htmlParserCtxtPtr ctxt;
2084
2085 /* if (repeat) */
2086 size = 4096;
2087 res = fread(chars, 1, 4, f);
2088 if (res > 0) {
2089 ctxt = htmlCreatePushParserCtxt(NULL, NULL,
William M. Brack1d75c8a2003-10-27 13:48:16 +00002090 chars, res, filename, XML_CHAR_ENCODING_NONE);
William M. Brack78637da2003-07-31 14:47:38 +00002091 while ((res = fread(chars, 1, size, f)) > 0) {
2092 htmlParseChunk(ctxt, chars, res, 0);
2093 }
2094 htmlParseChunk(ctxt, chars, 0, 1);
2095 doc = ctxt->myDoc;
2096 htmlFreeParserCtxt(ctxt);
2097 }
2098 fclose(f);
2099 }
2100 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00002101#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002102#ifdef HAVE_SYS_MMAN_H
2103 else if ((html) && (memory)) {
2104 int fd;
2105 struct stat info;
2106 const char *base;
2107 if (stat(filename, &info) < 0)
2108 return;
2109 if ((fd = open(filename, O_RDONLY)) < 0)
2110 return;
2111 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
2112 if (base == (void *) MAP_FAILED)
2113 return;
2114
2115 doc = htmlReadMemory((char *) base, info.st_size, filename,
2116 NULL, options);
2117
2118 munmap((char *) base, info.st_size);
2119 close(fd);
2120 }
2121#endif
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002122 else if (html) {
Daniel Veillard9475a352003-09-26 12:47:50 +00002123 doc = htmlReadFile(filename, NULL, options);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002124 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002125#endif /* LIBXML_HTML_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002126 else {
Daniel Veillard73b013f2003-09-30 12:36:01 +00002127#ifdef LIBXML_PUSH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002128 /*
2129 * build an XML tree from a string;
2130 */
2131 if (push) {
2132 FILE *f;
2133
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002134 /* '-' Usually means stdin -<sven@zen.org> */
2135 if ((filename[0] == '-') && (filename[1] == 0)) {
2136 f = stdin;
2137 } else {
William M. Brack3403add2004-06-27 02:07:51 +00002138#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2139 f = fopen(filename, "rb");
2140#else
2141 f = fopen(filename, "r");
2142#endif
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002143 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002144 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +00002145 int ret;
Daniel Veillarda880b122003-04-21 21:36:41 +00002146 int res, size = 1024;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002147 char chars[1024];
2148 xmlParserCtxtPtr ctxt;
2149
Daniel Veillarda880b122003-04-21 21:36:41 +00002150 /* if (repeat) size = 1024; */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002151 res = fread(chars, 1, 4, f);
2152 if (res > 0) {
2153 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
2154 chars, res, filename);
Daniel Veillard500a1de2004-03-22 15:22:58 +00002155 xmlCtxtUseOptions(ctxt, options);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002156 while ((res = fread(chars, 1, size, f)) > 0) {
2157 xmlParseChunk(ctxt, chars, res, 0);
2158 }
2159 xmlParseChunk(ctxt, chars, 0, 1);
2160 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +00002161 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002162 xmlFreeParserCtxt(ctxt);
Daniel Veillarde715dd22000-08-29 18:29:38 +00002163 if (!ret) {
2164 xmlFreeDoc(doc);
2165 doc = NULL;
2166 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002167 }
2168 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00002169 } else
2170#endif /* LIBXML_PUSH_ENABLED */
2171 if (testIO) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002172 if ((filename[0] == '-') && (filename[1] == 0)) {
Daniel Veillard60942de2003-09-25 21:05:58 +00002173 doc = xmlReadFd(0, NULL, NULL, options);
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002174 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002175 FILE *f;
Daniel Veillard5e873c42000-04-12 13:27:38 +00002176
William M. Brack3403add2004-06-27 02:07:51 +00002177#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2178 f = fopen(filename, "rb");
2179#else
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002180 f = fopen(filename, "r");
William M. Brack3403add2004-06-27 02:07:51 +00002181#endif
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002182 if (f != NULL) {
2183 if (rectxt == NULL)
2184 doc = xmlReadIO((xmlInputReadCallback) myRead,
2185 (xmlInputCloseCallback) myClose, f,
Daniel Veillard60942de2003-09-25 21:05:58 +00002186 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002187 else
2188 doc = xmlCtxtReadIO(rectxt,
2189 (xmlInputReadCallback) myRead,
2190 (xmlInputCloseCallback) myClose, f,
Daniel Veillard60942de2003-09-25 21:05:58 +00002191 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002192 } else
Daniel Veillard5e873c42000-04-12 13:27:38 +00002193 doc = NULL;
Daniel Veillard5e873c42000-04-12 13:27:38 +00002194 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002195 } else if (htmlout) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002196 xmlParserCtxtPtr ctxt;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002197
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002198 if (rectxt == NULL)
2199 ctxt = xmlNewParserCtxt();
2200 else
2201 ctxt = rectxt;
Daniel Veillard88a172f2000-08-04 18:23:10 +00002202 if (ctxt == NULL) {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002203 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +00002204 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002205 ctxt->sax->error = xmlHTMLError;
2206 ctxt->sax->warning = xmlHTMLWarning;
2207 ctxt->vctxt.error = xmlHTMLValidityError;
2208 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002209
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002210 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002211
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002212 if (rectxt == NULL)
2213 xmlFreeParserCtxt(ctxt);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002214 }
Daniel Veillard46e370e2000-07-21 20:32:03 +00002215#ifdef HAVE_SYS_MMAN_H
2216 } else if (memory) {
2217 int fd;
2218 struct stat info;
2219 const char *base;
2220 if (stat(filename, &info) < 0)
2221 return;
2222 if ((fd = open(filename, O_RDONLY)) < 0)
2223 return;
2224 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillard29579362000-08-14 17:57:48 +00002225 if (base == (void *) MAP_FAILED)
Daniel Veillard46e370e2000-07-21 20:32:03 +00002226 return;
2227
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002228 if (rectxt == NULL)
Daniel Veillard60942de2003-09-25 21:05:58 +00002229 doc = xmlReadMemory((char *) base, info.st_size,
2230 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002231 else
Daniel Veillard60942de2003-09-25 21:05:58 +00002232 doc = xmlCtxtReadMemory(rectxt, (char *) base, info.st_size,
2233 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002234
Daniel Veillard46e370e2000-07-21 20:32:03 +00002235 munmap((char *) base, info.st_size);
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002236 close(fd);
Daniel Veillard46e370e2000-07-21 20:32:03 +00002237#endif
Daniel Veillard4432df22003-09-28 18:58:27 +00002238#ifdef LIBXML_VALID_ENABLED
Daniel Veillardea7751d2002-12-20 00:16:24 +00002239 } else if (valid) {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002240 xmlParserCtxtPtr ctxt = NULL;
Daniel Veillardea7751d2002-12-20 00:16:24 +00002241
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002242 if (rectxt == NULL)
2243 ctxt = xmlNewParserCtxt();
2244 else
2245 ctxt = rectxt;
Daniel Veillardea7751d2002-12-20 00:16:24 +00002246 if (ctxt == NULL) {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002247 doc = NULL;
Daniel Veillardea7751d2002-12-20 00:16:24 +00002248 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002249 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
2250
2251 if (ctxt->valid == 0)
William M. Brack8304d872004-06-08 13:29:32 +00002252 progresult = XMLLINT_ERR_RDFILE;
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002253 if (rectxt == NULL)
2254 xmlFreeParserCtxt(ctxt);
Daniel Veillardea7751d2002-12-20 00:16:24 +00002255 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002256#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardea7751d2002-12-20 00:16:24 +00002257 } else {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002258 if (rectxt != NULL)
2259 doc = xmlCtxtReadFile(rectxt, filename, NULL, options);
Daniel Veillard81562d22005-06-15 13:27:56 +00002260 else {
2261#ifdef LIBXML_SAX1_ENABLED
2262 if (sax1)
2263 doc = xmlParseFile(filename);
2264 else
2265#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002266 doc = xmlReadFile(filename, NULL, options);
Daniel Veillard81562d22005-06-15 13:27:56 +00002267 }
Daniel Veillardea7751d2002-12-20 00:16:24 +00002268 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002269 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002270
Daniel Veillard88a172f2000-08-04 18:23:10 +00002271 /*
2272 * If we don't have a document we might as well give up. Do we
2273 * want an error message here? <sven@zen.org> */
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002274 if (doc == NULL) {
William M. Brack8304d872004-06-08 13:29:32 +00002275 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard88a172f2000-08-04 18:23:10 +00002276 return;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002277 }
2278
Daniel Veillard48b2f892001-02-25 16:11:03 +00002279 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002280 endTimer("Parsing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002281 }
2282
Daniel Veillard29e43992001-12-13 22:21:58 +00002283 /*
2284 * Remove DOCTYPE nodes
2285 */
2286 if (dropdtd) {
2287 xmlDtdPtr dtd;
2288
2289 dtd = xmlGetIntSubset(doc);
2290 if (dtd != NULL) {
2291 xmlUnlinkNode((xmlNodePtr)dtd);
2292 xmlFreeDtd(dtd);
2293 }
2294 }
2295
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002296#ifdef LIBXML_XINCLUDE_ENABLED
Daniel Veillard48b2f892001-02-25 16:11:03 +00002297 if (xinclude) {
2298 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002299 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002300 }
William M. Brack4e1c2db2005-02-11 10:58:55 +00002301 if (xmlXIncludeProcessFlags(doc, options) < 0)
2302 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard48b2f892001-02-25 16:11:03 +00002303 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002304 endTimer("Xinclude processing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002305 }
2306 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002307#endif
Daniel Veillard88a172f2000-08-04 18:23:10 +00002308
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002309#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00002310#ifdef LIBXML_XPATH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002311 /*
Daniel Veillardcbaf3992001-12-31 16:16:02 +00002312 * shell interaction
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002313 */
Daniel Veillard26a45c82006-10-20 12:55:34 +00002314 if (shell) {
2315 xmlXPathOrderDocElems(doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002316 xmlShell(doc, filename, xmlShellReadline, stdout);
Daniel Veillard26a45c82006-10-20 12:55:34 +00002317 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002318#endif
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00002319#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002320
Daniel Veillard652327a2003-09-29 18:02:38 +00002321#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002322 /*
2323 * test intermediate copy if needed.
2324 */
2325 if (copy) {
2326 tmp = doc;
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002327 if (timing) {
2328 startTimer();
2329 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002330 doc = xmlCopyDoc(doc, 1);
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002331 if (timing) {
2332 endTimer("Copying");
2333 }
2334 if (timing) {
2335 startTimer();
2336 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002337 xmlFreeDoc(tmp);
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002338 if (timing) {
2339 endTimer("Freeing original");
2340 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002341 }
Daniel Veillard652327a2003-09-29 18:02:38 +00002342#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002343
Daniel Veillard4432df22003-09-28 18:58:27 +00002344#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002345 if ((insert) && (!html)) {
2346 const xmlChar* list[256];
2347 int nb, i;
2348 xmlNodePtr node;
2349
2350 if (doc->children != NULL) {
2351 node = doc->children;
2352 while ((node != NULL) && (node->last == NULL)) node = node->next;
2353 if (node != NULL) {
2354 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
2355 if (nb < 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002356 fprintf(stderr, "could not get valid list of elements\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002357 } else if (nb == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002358 fprintf(stderr, "No element can be inserted under root\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002359 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002360 fprintf(stderr, "%d element types can be inserted under root:\n",
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002361 nb);
2362 for (i = 0;i < nb;i++) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002363 fprintf(stderr, "%s\n", (char *) list[i]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002364 }
2365 }
2366 }
2367 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002368 }else
2369#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002370#ifdef LIBXML_READER_ENABLED
2371 if (walker) {
2372 walkDoc(doc);
2373 }
2374#endif /* LIBXML_READER_ENABLED */
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002375#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard4432df22003-09-28 18:58:27 +00002376 if (noout == 0) {
Daniel Veillard3df01182003-12-10 10:17:51 +00002377 int ret;
2378
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002379 /*
2380 * print it.
2381 */
2382#ifdef LIBXML_DEBUG_ENABLED
2383 if (!debug) {
2384#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00002385 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002386 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002387 }
Daniel Veillard656ce942004-04-30 23:11:45 +00002388#ifdef LIBXML_HTML_ENABLED
Daniel Veillard42fd4122003-11-04 08:47:48 +00002389 if ((html) && (!xmlout)) {
2390 if (compress) {
2391 htmlSaveFile(output ? output : "-", doc);
2392 }
2393 else if (encoding != NULL) {
2394 if ( format ) {
2395 htmlSaveFileFormat(output ? output : "-", doc, encoding, 1);
2396 }
2397 else {
2398 htmlSaveFileFormat(output ? output : "-", doc, encoding, 0);
2399 }
2400 }
2401 else if (format) {
2402 htmlSaveFileFormat(output ? output : "-", doc, NULL, 1);
2403 }
2404 else {
2405 FILE *out;
2406 if (output == NULL)
2407 out = stdout;
2408 else {
2409 out = fopen(output,"wb");
2410 }
2411 if (out != NULL) {
2412 if (htmlDocDump(out, doc) < 0)
William M. Brack8304d872004-06-08 13:29:32 +00002413 progresult = XMLLINT_ERR_OUT;
Daniel Veillard42fd4122003-11-04 08:47:48 +00002414
2415 if (output != NULL)
2416 fclose(out);
2417 } else {
2418 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00002419 progresult = XMLLINT_ERR_OUT;
Daniel Veillard42fd4122003-11-04 08:47:48 +00002420 }
2421 }
2422 if ((timing) && (!repeat)) {
2423 endTimer("Saving");
2424 }
2425 } else
2426#endif
Daniel Veillard25048d82004-08-14 22:37:54 +00002427#ifdef LIBXML_C14N_ENABLED
2428 if (canonical) {
2429 xmlChar *result = NULL;
2430 int size;
2431
2432 size = xmlC14NDocDumpMemory(doc, NULL, 0, NULL, 1, &result);
2433 if (size >= 0) {
2434 write(1, result, size);
2435 xmlFree(result);
2436 } else {
2437 fprintf(stderr, "Failed to canonicalize\n");
2438 progresult = XMLLINT_ERR_OUT;
2439 }
2440 } else
Aleksey Sanin2650df12005-06-06 17:16:50 +00002441 if (exc_canonical) {
2442 xmlChar *result = NULL;
2443 int size;
2444
2445 size = xmlC14NDocDumpMemory(doc, NULL, 1, NULL, 1, &result);
2446 if (size >= 0) {
2447 write(1, result, size);
2448 xmlFree(result);
2449 } else {
2450 fprintf(stderr, "Failed to canonicalize\n");
2451 progresult = XMLLINT_ERR_OUT;
2452 }
2453 } else
Daniel Veillard25048d82004-08-14 22:37:54 +00002454#endif
Daniel Veillard3b2c2612001-04-04 00:09:00 +00002455#ifdef HAVE_SYS_MMAN_H
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002456 if (memory) {
2457 xmlChar *result;
2458 int len;
2459
2460 if (encoding != NULL) {
Daniel Veillardd536f702001-11-08 17:32:47 +00002461 if ( format ) {
2462 xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
2463 } else {
2464 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
2465 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002466 } else {
Daniel Veillard90493a92001-08-14 14:12:47 +00002467 if (format)
2468 xmlDocDumpFormatMemory(doc, &result, &len, 1);
2469 else
2470 xmlDocDumpMemory(doc, &result, &len);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002471 }
2472 if (result == NULL) {
2473 fprintf(stderr, "Failed to save\n");
Daniel Veillard25048d82004-08-14 22:37:54 +00002474 progresult = XMLLINT_ERR_OUT;
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002475 } else {
2476 write(1, result, len);
2477 xmlFree(result);
2478 }
Daniel Veillarddab39b52006-10-16 23:22:10 +00002479
Daniel Veillard3b2c2612001-04-04 00:09:00 +00002480 } else
2481#endif /* HAVE_SYS_MMAN_H */
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002482 if (compress) {
2483 xmlSaveFile(output ? output : "-", doc);
Daniel Veillarddab39b52006-10-16 23:22:10 +00002484 } else if (oldout) {
2485 if (encoding != NULL) {
2486 if ( format ) {
2487 ret = xmlSaveFormatFileEnc(output ? output : "-", doc,
2488 encoding, 1);
2489 }
2490 else {
2491 ret = xmlSaveFileEnc(output ? output : "-", doc,
2492 encoding);
2493 }
2494 if (ret < 0) {
2495 fprintf(stderr, "failed save to %s\n",
2496 output ? output : "-");
2497 progresult = XMLLINT_ERR_OUT;
2498 }
2499 } else if (format) {
2500 ret = xmlSaveFormatFile(output ? output : "-", doc, 1);
2501 if (ret < 0) {
2502 fprintf(stderr, "failed save to %s\n",
2503 output ? output : "-");
2504 progresult = XMLLINT_ERR_OUT;
2505 }
Daniel Veillard05d987b2003-10-08 11:54:57 +00002506 } else {
Daniel Veillarddab39b52006-10-16 23:22:10 +00002507 FILE *out;
2508 if (output == NULL)
2509 out = stdout;
2510 else {
2511 out = fopen(output,"wb");
2512 }
2513 if (out != NULL) {
2514 if (xmlDocDump(out, doc) < 0)
2515 progresult = XMLLINT_ERR_OUT;
2516
2517 if (output != NULL)
2518 fclose(out);
2519 } else {
2520 fprintf(stderr, "failed to open %s\n", output);
2521 progresult = XMLLINT_ERR_OUT;
2522 }
2523 }
2524 } else {
2525 xmlSaveCtxtPtr ctxt;
2526 int saveOpts = 0;
2527
2528 if (format)
2529 saveOpts |= XML_SAVE_FORMAT;
2530
2531 if (output == NULL)
2532 ctxt = xmlSaveToFd(1, encoding, saveOpts);
2533 else
2534 ctxt = xmlSaveToFilename(output, encoding, saveOpts);
2535
2536 if (ctxt != NULL) {
2537 if (xmlSaveDoc(ctxt, doc) < 0) {
2538 fprintf(stderr, "failed save to %s\n",
2539 output ? output : "-");
2540 progresult = XMLLINT_ERR_OUT;
2541 }
2542 xmlSaveClose(ctxt);
2543 } else {
William M. Brack8304d872004-06-08 13:29:32 +00002544 progresult = XMLLINT_ERR_OUT;
Daniel Veillard05d987b2003-10-08 11:54:57 +00002545 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002546 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002547 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002548 endTimer("Saving");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002549 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002550#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002551 } else {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002552 FILE *out;
2553 if (output == NULL)
2554 out = stdout;
2555 else {
2556 out = fopen(output,"wb");
2557 }
Daniel Veillard05d987b2003-10-08 11:54:57 +00002558 if (out != NULL) {
2559 xmlDebugDumpDocument(out, doc);
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002560
Daniel Veillard05d987b2003-10-08 11:54:57 +00002561 if (output != NULL)
2562 fclose(out);
2563 } else {
2564 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00002565 progresult = XMLLINT_ERR_OUT;
Daniel Veillard05d987b2003-10-08 11:54:57 +00002566 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002567 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002568#endif
2569 }
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002570#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002571
Daniel Veillard4432df22003-09-28 18:58:27 +00002572#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002573 /*
2574 * A posteriori validation test
2575 */
Daniel Veillard66f68e72003-08-18 16:39:51 +00002576 if ((dtdvalid != NULL) || (dtdvalidfpi != NULL)) {
Daniel Veillardcd429612000-10-11 15:57:05 +00002577 xmlDtdPtr dtd;
2578
Daniel Veillard48b2f892001-02-25 16:11:03 +00002579 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002580 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002581 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00002582 if (dtdvalid != NULL)
2583 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
2584 else
2585 dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL);
Daniel Veillard48b2f892001-02-25 16:11:03 +00002586 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002587 endTimer("Parsing DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002588 }
Daniel Veillardcd429612000-10-11 15:57:05 +00002589 if (dtd == NULL) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00002590 if (dtdvalid != NULL)
2591 xmlGenericError(xmlGenericErrorContext,
2592 "Could not parse DTD %s\n", dtdvalid);
2593 else
2594 xmlGenericError(xmlGenericErrorContext,
2595 "Could not parse DTD %s\n", dtdvalidfpi);
William M. Brack8304d872004-06-08 13:29:32 +00002596 progresult = XMLLINT_ERR_DTD;
Daniel Veillardcd429612000-10-11 15:57:05 +00002597 } else {
Daniel Veillarda37aab82003-06-09 09:10:36 +00002598 xmlValidCtxtPtr cvp;
2599
2600 if ((cvp = xmlNewValidCtxt()) == NULL) {
2601 xmlGenericError(xmlGenericErrorContext,
2602 "Couldn't allocate validation context\n");
2603 exit(-1);
2604 }
2605 cvp->userData = (void *) stderr;
2606 cvp->error = (xmlValidityErrorFunc) fprintf;
2607 cvp->warning = (xmlValidityWarningFunc) fprintf;
2608
Daniel Veillard48b2f892001-02-25 16:11:03 +00002609 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002610 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002611 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002612 if (!xmlValidateDtd(cvp, doc, dtd)) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00002613 if (dtdvalid != NULL)
2614 xmlGenericError(xmlGenericErrorContext,
2615 "Document %s does not validate against %s\n",
2616 filename, dtdvalid);
2617 else
2618 xmlGenericError(xmlGenericErrorContext,
2619 "Document %s does not validate against %s\n",
2620 filename, dtdvalidfpi);
William M. Brack8304d872004-06-08 13:29:32 +00002621 progresult = XMLLINT_ERR_VALID;
Daniel Veillardcd429612000-10-11 15:57:05 +00002622 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002623 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002624 endTimer("Validating against DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002625 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002626 xmlFreeValidCtxt(cvp);
Daniel Veillardcd429612000-10-11 15:57:05 +00002627 xmlFreeDtd(dtd);
2628 }
2629 } else if (postvalid) {
Daniel Veillarda37aab82003-06-09 09:10:36 +00002630 xmlValidCtxtPtr cvp;
2631
2632 if ((cvp = xmlNewValidCtxt()) == NULL) {
2633 xmlGenericError(xmlGenericErrorContext,
2634 "Couldn't allocate validation context\n");
2635 exit(-1);
2636 }
2637
Daniel Veillard48b2f892001-02-25 16:11:03 +00002638 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002639 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002640 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002641 cvp->userData = (void *) stderr;
2642 cvp->error = (xmlValidityErrorFunc) fprintf;
2643 cvp->warning = (xmlValidityWarningFunc) fprintf;
2644 if (!xmlValidateDocument(cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00002645 xmlGenericError(xmlGenericErrorContext,
2646 "Document %s does not validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002647 progresult = XMLLINT_ERR_VALID;
Daniel Veillardcd429612000-10-11 15:57:05 +00002648 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002649 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002650 endTimer("Validating");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002651 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002652 xmlFreeValidCtxt(cvp);
Daniel Veillard4432df22003-09-28 18:58:27 +00002653 }
2654#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardd4501d72005-07-24 14:27:16 +00002655#ifdef LIBXML_SCHEMATRON_ENABLED
2656 if (wxschematron != NULL) {
2657 xmlSchematronValidCtxtPtr ctxt;
2658 int ret;
Daniel Veillardc740a172005-07-31 12:17:24 +00002659 int flag;
Daniel Veillardd4501d72005-07-24 14:27:16 +00002660
2661 if ((timing) && (!repeat)) {
2662 startTimer();
2663 }
2664
2665 if (debug)
2666 flag = XML_SCHEMATRON_OUT_XML;
Daniel Veillardc740a172005-07-31 12:17:24 +00002667 else
2668 flag = XML_SCHEMATRON_OUT_TEXT;
2669 if (noout)
2670 flag |= XML_SCHEMATRON_OUT_QUIET;
Daniel Veillardd4501d72005-07-24 14:27:16 +00002671 ctxt = xmlSchematronNewValidCtxt(wxschematron, flag);
2672#if 0
2673 xmlSchematronSetValidErrors(ctxt,
2674 (xmlSchematronValidityErrorFunc) fprintf,
2675 (xmlSchematronValidityWarningFunc) fprintf,
2676 stderr);
2677#endif
2678 ret = xmlSchematronValidateDoc(ctxt, doc);
2679 if (ret == 0) {
2680 fprintf(stderr, "%s validates\n", filename);
2681 } else if (ret > 0) {
2682 fprintf(stderr, "%s fails to validate\n", filename);
2683 progresult = XMLLINT_ERR_VALID;
2684 } else {
2685 fprintf(stderr, "%s validation generated an internal error\n",
2686 filename);
2687 progresult = XMLLINT_ERR_VALID;
2688 }
2689 xmlSchematronFreeValidCtxt(ctxt);
2690 if ((timing) && (!repeat)) {
2691 endTimer("Validating");
2692 }
2693 }
2694#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00002695#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard4432df22003-09-28 18:58:27 +00002696 if (relaxngschemas != NULL) {
Daniel Veillard71531f32003-02-05 13:19:53 +00002697 xmlRelaxNGValidCtxtPtr ctxt;
2698 int ret;
2699
Daniel Veillard42f12e92003-03-07 18:32:59 +00002700 if ((timing) && (!repeat)) {
2701 startTimer();
2702 }
2703
Daniel Veillard71531f32003-02-05 13:19:53 +00002704 ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
2705 xmlRelaxNGSetValidErrors(ctxt,
2706 (xmlRelaxNGValidityErrorFunc) fprintf,
2707 (xmlRelaxNGValidityWarningFunc) fprintf,
2708 stderr);
2709 ret = xmlRelaxNGValidateDoc(ctxt, doc);
2710 if (ret == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002711 fprintf(stderr, "%s validates\n", filename);
Daniel Veillard71531f32003-02-05 13:19:53 +00002712 } else if (ret > 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002713 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002714 progresult = XMLLINT_ERR_VALID;
Daniel Veillard71531f32003-02-05 13:19:53 +00002715 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002716 fprintf(stderr, "%s validation generated an internal error\n",
Daniel Veillard71531f32003-02-05 13:19:53 +00002717 filename);
William M. Brack8304d872004-06-08 13:29:32 +00002718 progresult = XMLLINT_ERR_VALID;
Daniel Veillard71531f32003-02-05 13:19:53 +00002719 }
2720 xmlRelaxNGFreeValidCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00002721 if ((timing) && (!repeat)) {
2722 endTimer("Validating");
2723 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002724 } else if (wxschemas != NULL) {
2725 xmlSchemaValidCtxtPtr ctxt;
2726 int ret;
2727
2728 if ((timing) && (!repeat)) {
2729 startTimer();
2730 }
2731
2732 ctxt = xmlSchemaNewValidCtxt(wxschemas);
2733 xmlSchemaSetValidErrors(ctxt,
2734 (xmlSchemaValidityErrorFunc) fprintf,
2735 (xmlSchemaValidityWarningFunc) fprintf,
2736 stderr);
2737 ret = xmlSchemaValidateDoc(ctxt, doc);
2738 if (ret == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002739 fprintf(stderr, "%s validates\n", filename);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002740 } else if (ret > 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002741 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002742 progresult = XMLLINT_ERR_VALID;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002743 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002744 fprintf(stderr, "%s validation generated an internal error\n",
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002745 filename);
William M. Brack8304d872004-06-08 13:29:32 +00002746 progresult = XMLLINT_ERR_VALID;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002747 }
2748 xmlSchemaFreeValidCtxt(ctxt);
2749 if ((timing) && (!repeat)) {
2750 endTimer("Validating");
2751 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002752 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002753#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002754
2755#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillard6b099012008-11-06 13:47:39 +00002756#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002757 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00002758 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002759#endif
Daniel Veillard6b099012008-11-06 13:47:39 +00002760#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002761
2762 /*
2763 * free it.
2764 */
Daniel Veillard48b2f892001-02-25 16:11:03 +00002765 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002766 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002767 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002768 xmlFreeDoc(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +00002769 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002770 endTimer("Freeing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002771 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002772}
2773
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002774/************************************************************************
2775 * *
2776 * Usage and Main *
2777 * *
2778 ************************************************************************/
2779
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002780static void showVersion(const char *name) {
2781 fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
2782 fprintf(stderr, " compiled with: ");
Daniel Veillard602434d2005-09-12 09:20:31 +00002783 if (xmlHasFeature(XML_WITH_THREAD)) fprintf(stderr, "Threads ");
2784 if (xmlHasFeature(XML_WITH_TREE)) fprintf(stderr, "Tree ");
2785 if (xmlHasFeature(XML_WITH_OUTPUT)) fprintf(stderr, "Output ");
2786 if (xmlHasFeature(XML_WITH_PUSH)) fprintf(stderr, "Push ");
2787 if (xmlHasFeature(XML_WITH_READER)) fprintf(stderr, "Reader ");
2788 if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(stderr, "Patterns ");
2789 if (xmlHasFeature(XML_WITH_WRITER)) fprintf(stderr, "Writer ");
2790 if (xmlHasFeature(XML_WITH_SAX1)) fprintf(stderr, "SAXv1 ");
2791 if (xmlHasFeature(XML_WITH_FTP)) fprintf(stderr, "FTP ");
2792 if (xmlHasFeature(XML_WITH_HTTP)) fprintf(stderr, "HTTP ");
2793 if (xmlHasFeature(XML_WITH_VALID)) fprintf(stderr, "DTDValid ");
2794 if (xmlHasFeature(XML_WITH_HTML)) fprintf(stderr, "HTML ");
2795 if (xmlHasFeature(XML_WITH_LEGACY)) fprintf(stderr, "Legacy ");
2796 if (xmlHasFeature(XML_WITH_C14N)) fprintf(stderr, "C14N ");
2797 if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(stderr, "Catalog ");
2798 if (xmlHasFeature(XML_WITH_XPATH)) fprintf(stderr, "XPath ");
2799 if (xmlHasFeature(XML_WITH_XPTR)) fprintf(stderr, "XPointer ");
2800 if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(stderr, "XInclude ");
2801 if (xmlHasFeature(XML_WITH_ICONV)) fprintf(stderr, "Iconv ");
2802 if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(stderr, "ISO8859X ");
2803 if (xmlHasFeature(XML_WITH_UNICODE)) fprintf(stderr, "Unicode ");
2804 if (xmlHasFeature(XML_WITH_REGEXP)) fprintf(stderr, "Regexps ");
2805 if (xmlHasFeature(XML_WITH_AUTOMATA)) fprintf(stderr, "Automata ");
2806 if (xmlHasFeature(XML_WITH_EXPR)) fprintf(stderr, "Expr ");
2807 if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(stderr, "Schemas ");
2808 if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(stderr, "Schematron ");
2809 if (xmlHasFeature(XML_WITH_MODULES)) fprintf(stderr, "Modules ");
2810 if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(stderr, "Debug ");
2811 if (xmlHasFeature(XML_WITH_DEBUG_MEM)) fprintf(stderr, "MemDebug ");
2812 if (xmlHasFeature(XML_WITH_DEBUG_RUN)) fprintf(stderr, "RunDebug ");
Daniel Veillard75acfee2006-07-13 06:29:56 +00002813 if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(stderr, "Zlib ");
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002814 fprintf(stderr, "\n");
2815}
2816
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002817static void usage(const char *name) {
2818 printf("Usage : %s [options] XMLfiles ...\n", name);
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002819#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002820 printf("\tParse the XML files and output the result of the parsing\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002821#else
2822 printf("\tParse the XML files\n");
2823#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002824 printf("\t--version : display the version of the XML library used\n");
2825#ifdef LIBXML_DEBUG_ENABLED
2826 printf("\t--debug : dump a debug tree of the in-memory document\n");
2827 printf("\t--shell : run a navigating shell\n");
2828 printf("\t--debugent : debug the entities defined in the document\n");
Daniel Veillard8326e732003-01-07 00:19:07 +00002829#else
Daniel Veillard81273902003-09-30 00:43:48 +00002830#ifdef LIBXML_READER_ENABLED
Daniel Veillard8326e732003-01-07 00:19:07 +00002831 printf("\t--debug : dump the nodes content when using --stream\n");
Daniel Veillard81273902003-09-30 00:43:48 +00002832#endif /* LIBXML_READER_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002833#endif
Daniel Veillard652327a2003-09-29 18:02:38 +00002834#ifdef LIBXML_TREE_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002835 printf("\t--copy : used to test the internal copy implementation\n");
Daniel Veillard652327a2003-09-29 18:02:38 +00002836#endif /* LIBXML_TREE_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002837 printf("\t--recover : output what was parsable on broken XML documents\n");
Daniel Veillard8915c152008-08-26 13:05:34 +00002838 printf("\t--huge : remove any internal arbitrary parser limits\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002839 printf("\t--noent : substitute entity references by their value\n");
2840 printf("\t--noout : don't output the result tree\n");
Daniel Veillard0bff36d2004-08-31 09:37:03 +00002841 printf("\t--path 'paths': provide a set of paths for resources\n");
2842 printf("\t--load-trace : print trace of all external entites loaded\n");
Daniel Veillarde8b09e42003-05-13 22:14:13 +00002843 printf("\t--nonet : refuse to fetch DTDs or entities over network\n");
Daniel Veillard8874b942005-08-25 13:19:21 +00002844 printf("\t--nocompact : do not generate compact text nodes\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002845 printf("\t--htmlout : output results as HTML\n");
Daniel Veillard05c13a22001-09-09 08:38:09 +00002846 printf("\t--nowrap : do not put HTML doc wrapper\n");
Daniel Veillard4432df22003-09-28 18:58:27 +00002847#ifdef LIBXML_VALID_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002848 printf("\t--valid : validate the document in addition to std well-formed check\n");
2849 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
2850 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
Daniel Veillard66f68e72003-08-18 16:39:51 +00002851 printf("\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
Daniel Veillard4432df22003-09-28 18:58:27 +00002852#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002853 printf("\t--timing : print some timings\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002854 printf("\t--output file or -o file: save to a given file\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002855 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
2856 printf("\t--insert : ad-hoc test for valid insertions\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002857#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002858#ifdef HAVE_ZLIB_H
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002859 printf("\t--compress : turn on gzip compression of output\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002860#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002861#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002862#ifdef LIBXML_HTML_ENABLED
2863 printf("\t--html : use the HTML parser\n");
Daniel Veillard42fd4122003-11-04 08:47:48 +00002864 printf("\t--xmlout : force to use the XML serializer when using --html\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002865#endif
Daniel Veillard73b013f2003-09-30 12:36:01 +00002866#ifdef LIBXML_PUSH_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002867 printf("\t--push : use the push mode of the parser\n");
Daniel Veillard73b013f2003-09-30 12:36:01 +00002868#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002869#ifdef HAVE_SYS_MMAN_H
2870 printf("\t--memory : parse from memory\n");
2871#endif
Daniel Veillard87076042004-05-03 22:54:49 +00002872 printf("\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002873 printf("\t--nowarning : do not emit warnings from parser/validator\n");
2874 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
Daniel Veillarddca8cc72003-09-26 13:53:14 +00002875 printf("\t--nocdata : replace cdata section with text nodes\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002876#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard90493a92001-08-14 14:12:47 +00002877 printf("\t--format : reformat/reindent the input\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002878 printf("\t--encode encoding : output in the given encoding\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002879 printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
2880#endif /* LIBXML_OUTPUT_ENABLED */
Aleksey Sanin2650df12005-06-06 17:16:50 +00002881 printf("\t--c14n : save in W3C canonical format (with comments)\n");
2882 printf("\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n");
Daniel Veillard25048d82004-08-14 22:37:54 +00002883#ifdef LIBXML_C14N_ENABLED
2884#endif /* LIBXML_C14N_ENABLED */
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002885 printf("\t--nsclean : remove redundant namespace declarations\n");
2886 printf("\t--testIO : test user I/O support\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002887#ifdef LIBXML_CATALOG_ENABLED
Daniel Veillardbd9b0e82001-11-26 10:32:08 +00002888 printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
2889 printf("\t otherwise XML Catalogs starting from \n");
Daniel Veillardb3de70c2003-12-02 22:32:15 +00002890 printf("\t %s are activated by default\n", XML_XML_DEFAULT_CATALOG);
Daniel Veillard05c13a22001-09-09 08:38:09 +00002891 printf("\t--nocatalogs: deactivate all catalogs\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002892#endif
2893 printf("\t--auto : generate a small doc on the fly\n");
2894#ifdef LIBXML_XINCLUDE_ENABLED
2895 printf("\t--xinclude : do XInclude processing\n");
Daniel Veillardc14c3892004-08-16 12:34:50 +00002896 printf("\t--noxincludenode : same but do not generate XInclude nodes\n");
Daniel Veillard54bd29b2008-08-26 07:26:55 +00002897 printf("\t--nofixup-base-uris : do not fixup xml:base uris\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002898#endif
Daniel Veillardcbaf3992001-12-31 16:16:02 +00002899 printf("\t--loaddtd : fetch external DTD\n");
Daniel Veillard48da9102001-08-07 01:10:10 +00002900 printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
Daniel Veillard81273902003-09-30 00:43:48 +00002901#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00002902 printf("\t--stream : use the streaming interface to process very large files\n");
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002903 printf("\t--walker : create a reader and walk though the resulting doc\n");
Daniel Veillard81273902003-09-30 00:43:48 +00002904#endif /* LIBXML_READER_ENABLED */
Daniel Veillardb3de70c2003-12-02 22:32:15 +00002905#ifdef LIBXML_PATTERN_ENABLED
2906 printf("\t--pattern pattern_value : test the pattern support\n");
2907#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00002908 printf("\t--chkregister : verify the node registration code\n");
Daniel Veillardef4d3bc2003-02-07 12:38:22 +00002909#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard71531f32003-02-05 13:19:53 +00002910 printf("\t--relaxng schema : do RelaxNG validation against the schema\n");
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002911 printf("\t--schema schema : do validation against the WXS schema\n");
Daniel Veillard71531f32003-02-05 13:19:53 +00002912#endif
Daniel Veillarde70375c2005-07-30 21:09:12 +00002913#ifdef LIBXML_SCHEMATRON_ENABLED
2914 printf("\t--schematron schema : do validation against a schematron\n");
2915#endif
Daniel Veillard971771e2005-07-09 17:32:57 +00002916#ifdef LIBXML_SAX1_ENABLED
2917 printf("\t--sax1: use the old SAX1 interfaces for processing\n");
2918#endif
2919 printf("\t--sax: do not build a tree but work just at the SAX level\n");
Daniel Veillard7e5c3f42008-07-29 16:12:31 +00002920 printf("\t--oldxml10: use XML-1.0 parsing rules before the 5th edition\n");
Daniel Veillard971771e2005-07-09 17:32:57 +00002921
Daniel Veillarda42f25f2002-01-25 14:15:40 +00002922 printf("\nLibxml project home page: http://xmlsoft.org/\n");
2923 printf("To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002924}
Daniel Veillard8a1b1852003-01-05 22:37:17 +00002925
2926static void registerNode(xmlNodePtr node)
2927{
2928 node->_private = malloc(sizeof(long));
2929 *(long*)node->_private = (long) 0x81726354;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00002930 nbregister++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00002931}
2932
2933static void deregisterNode(xmlNodePtr node)
2934{
2935 assert(node->_private != NULL);
2936 assert(*(long*)node->_private == (long) 0x81726354);
2937 free(node->_private);
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00002938 nbregister--;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00002939}
2940
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002941int
2942main(int argc, char **argv) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00002943 int i, acount;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002944 int files = 0;
Daniel Veillard845cce42002-01-09 11:51:37 +00002945 int version = 0;
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00002946 const char* indent;
2947
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002948 if (argc <= 1) {
2949 usage(argv[0]);
2950 return(1);
2951 }
Daniel Veillardbe803962000-06-28 23:40:59 +00002952 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002953 for (i = 1; i < argc ; i++) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002954 if (!strcmp(argv[i], "-"))
2955 break;
2956
2957 if (argv[i][0] != '-')
2958 continue;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002959 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
2960 debug++;
Daniel Veillard56ada1d2003-01-07 11:17:25 +00002961 else
2962#ifdef LIBXML_DEBUG_ENABLED
2963 if ((!strcmp(argv[i], "-shell")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002964 (!strcmp(argv[i], "--shell"))) {
2965 shell++;
2966 noout = 1;
2967 } else
2968#endif
Daniel Veillard652327a2003-09-29 18:02:38 +00002969#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002970 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
2971 copy++;
Daniel Veillard652327a2003-09-29 18:02:38 +00002972 else
2973#endif /* LIBXML_TREE_ENABLED */
2974 if ((!strcmp(argv[i], "-recover")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002975 (!strcmp(argv[i], "--recover"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002976 recovery++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002977 options |= XML_PARSE_RECOVER;
Daniel Veillard8915c152008-08-26 13:05:34 +00002978 } else if ((!strcmp(argv[i], "-huge")) ||
2979 (!strcmp(argv[i], "--huge"))) {
2980 options |= XML_PARSE_HUGE;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002981 } else if ((!strcmp(argv[i], "-noent")) ||
2982 (!strcmp(argv[i], "--noent"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002983 noent++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002984 options |= XML_PARSE_NOENT;
Daniel Veillarddca8cc72003-09-26 13:53:14 +00002985 } else if ((!strcmp(argv[i], "-nsclean")) ||
2986 (!strcmp(argv[i], "--nsclean"))) {
2987 options |= XML_PARSE_NSCLEAN;
2988 } else if ((!strcmp(argv[i], "-nocdata")) ||
2989 (!strcmp(argv[i], "--nocdata"))) {
2990 options |= XML_PARSE_NOCDATA;
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002991 } else if ((!strcmp(argv[i], "-nodict")) ||
2992 (!strcmp(argv[i], "--nodict"))) {
2993 options |= XML_PARSE_NODICT;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002994 } else if ((!strcmp(argv[i], "-version")) ||
Daniel Veillard845cce42002-01-09 11:51:37 +00002995 (!strcmp(argv[i], "--version"))) {
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002996 showVersion(argv[0]);
Daniel Veillard845cce42002-01-09 11:51:37 +00002997 version = 1;
2998 } else if ((!strcmp(argv[i], "-noout")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002999 (!strcmp(argv[i], "--noout")))
3000 noout++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003001#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003002 else if ((!strcmp(argv[i], "-o")) ||
3003 (!strcmp(argv[i], "-output")) ||
3004 (!strcmp(argv[i], "--output"))) {
3005 i++;
Daniel Veillard6e4f1c02002-04-09 09:55:20 +00003006 output = argv[i];
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003007 }
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003008#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003009 else if ((!strcmp(argv[i], "-htmlout")) ||
3010 (!strcmp(argv[i], "--htmlout")))
3011 htmlout++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003012 else if ((!strcmp(argv[i], "-nowrap")) ||
3013 (!strcmp(argv[i], "--nowrap")))
3014 nowrap++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003015#ifdef LIBXML_HTML_ENABLED
3016 else if ((!strcmp(argv[i], "-html")) ||
3017 (!strcmp(argv[i], "--html"))) {
3018 html++;
3019 }
Daniel Veillard42fd4122003-11-04 08:47:48 +00003020 else if ((!strcmp(argv[i], "-xmlout")) ||
3021 (!strcmp(argv[i], "--xmlout"))) {
3022 xmlout++;
3023 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003024#endif /* LIBXML_HTML_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003025 else if ((!strcmp(argv[i], "-loaddtd")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003026 (!strcmp(argv[i], "--loaddtd"))) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003027 loaddtd++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003028 options |= XML_PARSE_DTDLOAD;
3029 } else if ((!strcmp(argv[i], "-dtdattr")) ||
Daniel Veillard48da9102001-08-07 01:10:10 +00003030 (!strcmp(argv[i], "--dtdattr"))) {
3031 loaddtd++;
3032 dtdattrs++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003033 options |= XML_PARSE_DTDATTR;
Daniel Veillard4432df22003-09-28 18:58:27 +00003034 }
3035#ifdef LIBXML_VALID_ENABLED
3036 else if ((!strcmp(argv[i], "-valid")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003037 (!strcmp(argv[i], "--valid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003038 valid++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003039 options |= XML_PARSE_DTDVALID;
3040 } else if ((!strcmp(argv[i], "-postvalid")) ||
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003041 (!strcmp(argv[i], "--postvalid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003042 postvalid++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003043 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003044 options |= XML_PARSE_DTDLOAD;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003045 } else if ((!strcmp(argv[i], "-dtdvalid")) ||
Daniel Veillardcd429612000-10-11 15:57:05 +00003046 (!strcmp(argv[i], "--dtdvalid"))) {
3047 i++;
3048 dtdvalid = argv[i];
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003049 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003050 options |= XML_PARSE_DTDLOAD;
Daniel Veillard66f68e72003-08-18 16:39:51 +00003051 } else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3052 (!strcmp(argv[i], "--dtdvalidfpi"))) {
3053 i++;
3054 dtdvalidfpi = argv[i];
3055 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003056 options |= XML_PARSE_DTDLOAD;
Daniel Veillardcd429612000-10-11 15:57:05 +00003057 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003058#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard29e43992001-12-13 22:21:58 +00003059 else if ((!strcmp(argv[i], "-dropdtd")) ||
3060 (!strcmp(argv[i], "--dropdtd")))
3061 dropdtd++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003062 else if ((!strcmp(argv[i], "-insert")) ||
3063 (!strcmp(argv[i], "--insert")))
3064 insert++;
Daniel Veillard48b2f892001-02-25 16:11:03 +00003065 else if ((!strcmp(argv[i], "-timing")) ||
3066 (!strcmp(argv[i], "--timing")))
3067 timing++;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00003068 else if ((!strcmp(argv[i], "-auto")) ||
3069 (!strcmp(argv[i], "--auto")))
3070 generate++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003071 else if ((!strcmp(argv[i], "-repeat")) ||
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00003072 (!strcmp(argv[i], "--repeat"))) {
3073 if (repeat)
3074 repeat *= 10;
3075 else
3076 repeat = 100;
Daniel Veillard73b013f2003-09-30 12:36:01 +00003077 }
3078#ifdef LIBXML_PUSH_ENABLED
3079 else if ((!strcmp(argv[i], "-push")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003080 (!strcmp(argv[i], "--push")))
3081 push++;
Daniel Veillard73b013f2003-09-30 12:36:01 +00003082#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillard46e370e2000-07-21 20:32:03 +00003083#ifdef HAVE_SYS_MMAN_H
3084 else if ((!strcmp(argv[i], "-memory")) ||
3085 (!strcmp(argv[i], "--memory")))
3086 memory++;
3087#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +00003088 else if ((!strcmp(argv[i], "-testIO")) ||
3089 (!strcmp(argv[i], "--testIO")))
3090 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003091#ifdef LIBXML_XINCLUDE_ENABLED
3092 else if ((!strcmp(argv[i], "-xinclude")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003093 (!strcmp(argv[i], "--xinclude"))) {
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003094 xinclude++;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003095 options |= XML_PARSE_XINCLUDE;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003096 }
Daniel Veillardc14c3892004-08-16 12:34:50 +00003097 else if ((!strcmp(argv[i], "-noxincludenode")) ||
3098 (!strcmp(argv[i], "--noxincludenode"))) {
3099 xinclude++;
3100 options |= XML_PARSE_XINCLUDE;
3101 options |= XML_PARSE_NOXINCNODE;
3102 }
Daniel Veillard54bd29b2008-08-26 07:26:55 +00003103 else if ((!strcmp(argv[i], "-nofixup-base-uris")) ||
3104 (!strcmp(argv[i], "--nofixup-base-uris"))) {
3105 xinclude++;
3106 options |= XML_PARSE_XINCLUDE;
3107 options |= XML_PARSE_NOBASEFIX;
3108 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003109#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003110#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003111#ifdef HAVE_ZLIB_H
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003112 else if ((!strcmp(argv[i], "-compress")) ||
3113 (!strcmp(argv[i], "--compress"))) {
3114 compress++;
3115 xmlSetCompressMode(9);
3116 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003117#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003118#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003119 else if ((!strcmp(argv[i], "-nowarning")) ||
3120 (!strcmp(argv[i], "--nowarning"))) {
3121 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003122 xmlPedanticParserDefault(0);
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003123 options |= XML_PARSE_NOWARNING;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003124 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003125 else if ((!strcmp(argv[i], "-pedantic")) ||
3126 (!strcmp(argv[i], "--pedantic"))) {
3127 xmlGetWarningsDefaultValue = 1;
3128 xmlPedanticParserDefault(1);
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003129 options |= XML_PARSE_PEDANTIC;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003130 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00003131#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003132 else if ((!strcmp(argv[i], "-debugent")) ||
3133 (!strcmp(argv[i], "--debugent"))) {
3134 debugent++;
3135 xmlParserDebugEntities = 1;
3136 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00003137#endif
Daniel Veillard25048d82004-08-14 22:37:54 +00003138#ifdef LIBXML_C14N_ENABLED
3139 else if ((!strcmp(argv[i], "-c14n")) ||
3140 (!strcmp(argv[i], "--c14n"))) {
3141 canonical++;
3142 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
3143 }
Aleksey Sanin2650df12005-06-06 17:16:50 +00003144 else if ((!strcmp(argv[i], "-exc-c14n")) ||
3145 (!strcmp(argv[i], "--exc-c14n"))) {
3146 exc_canonical++;
3147 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
3148 }
Daniel Veillard25048d82004-08-14 22:37:54 +00003149#endif
Daniel Veillard81418e32001-05-22 15:08:55 +00003150#ifdef LIBXML_CATALOG_ENABLED
3151 else if ((!strcmp(argv[i], "-catalogs")) ||
3152 (!strcmp(argv[i], "--catalogs"))) {
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003153 catalogs++;
3154 } else if ((!strcmp(argv[i], "-nocatalogs")) ||
3155 (!strcmp(argv[i], "--nocatalogs"))) {
3156 nocatalogs++;
Daniel Veillard81418e32001-05-22 15:08:55 +00003157 }
3158#endif
Daniel Veillardbe803962000-06-28 23:40:59 +00003159 else if ((!strcmp(argv[i], "-encode")) ||
3160 (!strcmp(argv[i], "--encode"))) {
3161 i++;
3162 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003163 /*
3164 * OK it's for testing purposes
3165 */
3166 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +00003167 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003168 else if ((!strcmp(argv[i], "-noblanks")) ||
3169 (!strcmp(argv[i], "--noblanks"))) {
3170 noblanks++;
3171 xmlKeepBlanksDefault(0);
Daniel Veillard90493a92001-08-14 14:12:47 +00003172 }
Daniel Veillard87076042004-05-03 22:54:49 +00003173 else if ((!strcmp(argv[i], "-maxmem")) ||
3174 (!strcmp(argv[i], "--maxmem"))) {
3175 i++;
3176 if (sscanf(argv[i], "%d", &maxmem) == 1) {
3177 xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc,
3178 myStrdupFunc);
3179 } else {
3180 maxmem = 0;
3181 }
3182 }
Daniel Veillard90493a92001-08-14 14:12:47 +00003183 else if ((!strcmp(argv[i], "-format")) ||
3184 (!strcmp(argv[i], "--format"))) {
3185 noblanks++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003186#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard90493a92001-08-14 14:12:47 +00003187 format++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003188#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard90493a92001-08-14 14:12:47 +00003189 xmlKeepBlanksDefault(0);
Daniel Veillard7704fb12003-01-03 16:19:51 +00003190 }
Daniel Veillard81273902003-09-30 00:43:48 +00003191#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003192 else if ((!strcmp(argv[i], "-stream")) ||
3193 (!strcmp(argv[i], "--stream"))) {
3194 stream++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003195 }
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003196 else if ((!strcmp(argv[i], "-walker")) ||
3197 (!strcmp(argv[i], "--walker"))) {
3198 walker++;
3199 noout++;
3200 }
Daniel Veillard81273902003-09-30 00:43:48 +00003201#endif /* LIBXML_READER_ENABLED */
3202#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +00003203 else if ((!strcmp(argv[i], "-sax1")) ||
3204 (!strcmp(argv[i], "--sax1"))) {
3205 sax1++;
3206 }
Daniel Veillard81273902003-09-30 00:43:48 +00003207#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003208 else if ((!strcmp(argv[i], "-sax")) ||
3209 (!strcmp(argv[i], "--sax"))) {
3210 sax++;
3211 }
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003212 else if ((!strcmp(argv[i], "-chkregister")) ||
3213 (!strcmp(argv[i], "--chkregister"))) {
3214 chkregister++;
Daniel Veillard71531f32003-02-05 13:19:53 +00003215#ifdef LIBXML_SCHEMAS_ENABLED
3216 } else if ((!strcmp(argv[i], "-relaxng")) ||
3217 (!strcmp(argv[i], "--relaxng"))) {
3218 i++;
3219 relaxng = argv[i];
3220 noent++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003221 options |= XML_PARSE_NOENT;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003222 } else if ((!strcmp(argv[i], "-schema")) ||
3223 (!strcmp(argv[i], "--schema"))) {
3224 i++;
3225 schema = argv[i];
3226 noent++;
Daniel Veillard71531f32003-02-05 13:19:53 +00003227#endif
Daniel Veillardd4501d72005-07-24 14:27:16 +00003228#ifdef LIBXML_SCHEMATRON_ENABLED
3229 } else if ((!strcmp(argv[i], "-schematron")) ||
3230 (!strcmp(argv[i], "--schematron"))) {
3231 i++;
3232 schematron = argv[i];
3233 noent++;
3234#endif
Daniel Veillarde8b09e42003-05-13 22:14:13 +00003235 } else if ((!strcmp(argv[i], "-nonet")) ||
3236 (!strcmp(argv[i], "--nonet"))) {
Daniel Veillard61b93382003-11-03 14:28:31 +00003237 options |= XML_PARSE_NONET;
Daniel Veillard968d6432006-04-25 16:17:53 +00003238 xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
Daniel Veillard8874b942005-08-25 13:19:21 +00003239 } else if ((!strcmp(argv[i], "-nocompact")) ||
3240 (!strcmp(argv[i], "--nocompact"))) {
3241 options &= ~XML_PARSE_COMPACT;
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003242 } else if ((!strcmp(argv[i], "-load-trace")) ||
3243 (!strcmp(argv[i], "--load-trace"))) {
3244 load_trace++;
3245 } else if ((!strcmp(argv[i], "-path")) ||
3246 (!strcmp(argv[i], "--path"))) {
3247 i++;
3248 parsePath(BAD_CAST argv[i]);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003249#ifdef LIBXML_PATTERN_ENABLED
3250 } else if ((!strcmp(argv[i], "-pattern")) ||
3251 (!strcmp(argv[i], "--pattern"))) {
3252 i++;
3253 pattern = argv[i];
3254#endif
Daniel Veillard7e5c3f42008-07-29 16:12:31 +00003255 } else if ((!strcmp(argv[i], "-oldxml10")) ||
3256 (!strcmp(argv[i], "--oldxml10"))) {
3257 oldxml10++;
3258 options |= XML_PARSE_OLD10;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003259 } else {
3260 fprintf(stderr, "Unknown option %s\n", argv[i]);
3261 usage(argv[0]);
3262 return(1);
3263 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003264 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003265
3266#ifdef LIBXML_CATALOG_ENABLED
3267 if (nocatalogs == 0) {
3268 if (catalogs) {
3269 const char *catal;
3270
3271 catal = getenv("SGML_CATALOG_FILES");
Daniel Veillard6c5f9d12001-08-25 13:33:14 +00003272 if (catal != NULL) {
3273 xmlLoadCatalogs(catal);
3274 } else {
3275 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
3276 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003277 }
3278 }
3279#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003280
Daniel Veillard81273902003-09-30 00:43:48 +00003281#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +00003282 if (sax1)
3283 xmlSAXDefaultVersion(1);
3284 else
3285 xmlSAXDefaultVersion(2);
Daniel Veillard81273902003-09-30 00:43:48 +00003286#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillard07cb8222003-09-10 10:51:05 +00003287
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003288 if (chkregister) {
3289 xmlRegisterNodeDefault(registerNode);
3290 xmlDeregisterNodeDefault(deregisterNode);
3291 }
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00003292
3293 indent = getenv("XMLLINT_INDENT");
3294 if(indent != NULL) {
3295 xmlTreeIndentString = indent;
3296 }
3297
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003298
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003299 defaultEntityLoader = xmlGetExternalEntityLoader();
3300 xmlSetExternalEntityLoader(xmllintExternalEntityLoader);
3301
Daniel Veillardd9bad132001-07-23 19:39:43 +00003302 xmlLineNumbersDefault(1);
Daniel Veillard48da9102001-08-07 01:10:10 +00003303 if (loaddtd != 0)
3304 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
3305 if (dtdattrs)
3306 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003307 if (noent != 0) xmlSubstituteEntitiesDefault(1);
Daniel Veillard4432df22003-09-28 18:58:27 +00003308#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003309 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
Daniel Veillard4432df22003-09-28 18:58:27 +00003310#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003311 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003312 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003313 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003314 xmlGenericError(xmlGenericErrorContext,
3315 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
3316 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003317 "<html><head><title>%s output</title></head>\n",
3318 argv[0]);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003319 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003320 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
3321 argv[0]);
3322 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003323
Daniel Veillardd4501d72005-07-24 14:27:16 +00003324#ifdef LIBXML_SCHEMATRON_ENABLED
3325 if ((schematron != NULL) && (sax == 0)
3326#ifdef LIBXML_READER_ENABLED
3327 && (stream == 0)
3328#endif /* LIBXML_READER_ENABLED */
3329 ) {
3330 xmlSchematronParserCtxtPtr ctxt;
3331
3332 /* forces loading the DTDs */
3333 xmlLoadExtDtdDefaultValue |= 1;
3334 options |= XML_PARSE_DTDLOAD;
3335 if (timing) {
3336 startTimer();
3337 }
3338 ctxt = xmlSchematronNewParserCtxt(schematron);
3339#if 0
3340 xmlSchematronSetParserErrors(ctxt,
3341 (xmlSchematronValidityErrorFunc) fprintf,
3342 (xmlSchematronValidityWarningFunc) fprintf,
3343 stderr);
3344#endif
3345 wxschematron = xmlSchematronParse(ctxt);
3346 if (wxschematron == NULL) {
3347 xmlGenericError(xmlGenericErrorContext,
3348 "Schematron schema %s failed to compile\n", schematron);
3349 progresult = XMLLINT_ERR_SCHEMACOMP;
3350 schematron = NULL;
3351 }
3352 xmlSchematronFreeParserCtxt(ctxt);
3353 if (timing) {
3354 endTimer("Compiling the schemas");
3355 }
3356 }
3357#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00003358#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003359 if ((relaxng != NULL) && (sax == 0)
Daniel Veillard81273902003-09-30 00:43:48 +00003360#ifdef LIBXML_READER_ENABLED
3361 && (stream == 0)
3362#endif /* LIBXML_READER_ENABLED */
3363 ) {
Daniel Veillard71531f32003-02-05 13:19:53 +00003364 xmlRelaxNGParserCtxtPtr ctxt;
3365
Daniel Veillardce192eb2003-04-16 15:58:05 +00003366 /* forces loading the DTDs */
3367 xmlLoadExtDtdDefaultValue |= 1;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003368 options |= XML_PARSE_DTDLOAD;
Daniel Veillard42f12e92003-03-07 18:32:59 +00003369 if (timing) {
3370 startTimer();
3371 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003372 ctxt = xmlRelaxNGNewParserCtxt(relaxng);
3373 xmlRelaxNGSetParserErrors(ctxt,
3374 (xmlRelaxNGValidityErrorFunc) fprintf,
3375 (xmlRelaxNGValidityWarningFunc) fprintf,
3376 stderr);
3377 relaxngschemas = xmlRelaxNGParse(ctxt);
Daniel Veillardce192eb2003-04-16 15:58:05 +00003378 if (relaxngschemas == NULL) {
3379 xmlGenericError(xmlGenericErrorContext,
3380 "Relax-NG schema %s failed to compile\n", relaxng);
William M. Brack8304d872004-06-08 13:29:32 +00003381 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillardce192eb2003-04-16 15:58:05 +00003382 relaxng = NULL;
3383 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003384 xmlRelaxNGFreeParserCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00003385 if (timing) {
3386 endTimer("Compiling the schemas");
3387 }
Daniel Veillardebe25d42004-03-25 09:35:49 +00003388 } else if ((schema != NULL)
3389#ifdef LIBXML_READER_ENABLED
Daniel Veillardf10ae122005-07-10 19:03:16 +00003390 && (stream == 0)
Daniel Veillardebe25d42004-03-25 09:35:49 +00003391#endif
3392 ) {
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003393 xmlSchemaParserCtxtPtr ctxt;
3394
3395 if (timing) {
3396 startTimer();
3397 }
3398 ctxt = xmlSchemaNewParserCtxt(schema);
3399 xmlSchemaSetParserErrors(ctxt,
3400 (xmlSchemaValidityErrorFunc) fprintf,
3401 (xmlSchemaValidityWarningFunc) fprintf,
3402 stderr);
3403 wxschemas = xmlSchemaParse(ctxt);
3404 if (wxschemas == NULL) {
3405 xmlGenericError(xmlGenericErrorContext,
3406 "WXS schema %s failed to compile\n", schema);
William M. Brack8304d872004-06-08 13:29:32 +00003407 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003408 schema = NULL;
3409 }
3410 xmlSchemaFreeParserCtxt(ctxt);
3411 if (timing) {
3412 endTimer("Compiling the schemas");
3413 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003414 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003415#endif /* LIBXML_SCHEMAS_ENABLED */
3416#ifdef LIBXML_PATTERN_ENABLED
Daniel Veillard39e5c892005-07-03 22:48:50 +00003417 if ((pattern != NULL)
Daniel Veillardc9352532005-07-04 14:25:34 +00003418#ifdef LIBXML_READER_ENABLED
Daniel Veillard39e5c892005-07-03 22:48:50 +00003419 && (walker == 0)
3420#endif
3421 ) {
Daniel Veillardffa7b7e2003-12-05 16:10:21 +00003422 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003423 if (patternc == NULL) {
3424 xmlGenericError(xmlGenericErrorContext,
3425 "Pattern %s failed to compile\n", pattern);
William M. Brack8304d872004-06-08 13:29:32 +00003426 progresult = XMLLINT_ERR_SCHEMAPAT;
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003427 pattern = NULL;
3428 }
3429 }
3430#endif /* LIBXML_PATTERN_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003431 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +00003432 if ((!strcmp(argv[i], "-encode")) ||
3433 (!strcmp(argv[i], "--encode"))) {
3434 i++;
3435 continue;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003436 } else if ((!strcmp(argv[i], "-o")) ||
3437 (!strcmp(argv[i], "-output")) ||
3438 (!strcmp(argv[i], "--output"))) {
3439 i++;
3440 continue;
Daniel Veillardbe803962000-06-28 23:40:59 +00003441 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003442#ifdef LIBXML_VALID_ENABLED
Daniel Veillardcd429612000-10-11 15:57:05 +00003443 if ((!strcmp(argv[i], "-dtdvalid")) ||
3444 (!strcmp(argv[i], "--dtdvalid"))) {
3445 i++;
3446 continue;
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003447 }
3448 if ((!strcmp(argv[i], "-path")) ||
3449 (!strcmp(argv[i], "--path"))) {
3450 i++;
3451 continue;
Daniel Veillardcd429612000-10-11 15:57:05 +00003452 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00003453 if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3454 (!strcmp(argv[i], "--dtdvalidfpi"))) {
3455 i++;
3456 continue;
3457 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003458#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard71531f32003-02-05 13:19:53 +00003459 if ((!strcmp(argv[i], "-relaxng")) ||
3460 (!strcmp(argv[i], "--relaxng"))) {
3461 i++;
3462 continue;
3463 }
Daniel Veillard87076042004-05-03 22:54:49 +00003464 if ((!strcmp(argv[i], "-maxmem")) ||
3465 (!strcmp(argv[i], "--maxmem"))) {
3466 i++;
3467 continue;
3468 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003469 if ((!strcmp(argv[i], "-schema")) ||
3470 (!strcmp(argv[i], "--schema"))) {
3471 i++;
3472 continue;
3473 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00003474 if ((!strcmp(argv[i], "-schematron")) ||
3475 (!strcmp(argv[i], "--schematron"))) {
3476 i++;
3477 continue;
3478 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003479#ifdef LIBXML_PATTERN_ENABLED
3480 if ((!strcmp(argv[i], "-pattern")) ||
3481 (!strcmp(argv[i], "--pattern"))) {
3482 i++;
3483 continue;
3484 }
3485#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00003486 if ((timing) && (repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00003487 startTimer();
Daniel Veillardcbaf3992001-12-31 16:16:02 +00003488 /* Remember file names. "-" means stdin. <sven@zen.org> */
Daniel Veillard4a6845d2001-01-03 13:32:39 +00003489 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003490 if (repeat) {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003491 xmlParserCtxtPtr ctxt = NULL;
3492
3493 for (acount = 0;acount < repeat;acount++) {
Daniel Veillard81273902003-09-30 00:43:48 +00003494#ifdef LIBXML_READER_ENABLED
Daniel Veillard198c1bf2003-10-20 17:07:41 +00003495 if (stream != 0) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00003496 streamFile(argv[i]);
Daniel Veillard198c1bf2003-10-20 17:07:41 +00003497 } else {
Daniel Veillard81273902003-09-30 00:43:48 +00003498#endif /* LIBXML_READER_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003499 if (sax) {
3500 testSAX(argv[i]);
3501 } else {
3502 if (ctxt == NULL)
3503 ctxt = xmlNewParserCtxt();
3504 parseAndPrintFile(argv[i], ctxt);
3505 }
Daniel Veillard81273902003-09-30 00:43:48 +00003506#ifdef LIBXML_READER_ENABLED
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003507 }
Daniel Veillard81273902003-09-30 00:43:48 +00003508#endif /* LIBXML_READER_ENABLED */
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003509 }
3510 if (ctxt != NULL)
3511 xmlFreeParserCtxt(ctxt);
Daniel Veillard7704fb12003-01-03 16:19:51 +00003512 } else {
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003513 nbregister = 0;
3514
Daniel Veillard81273902003-09-30 00:43:48 +00003515#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003516 if (stream != 0)
3517 streamFile(argv[i]);
3518 else
Daniel Veillard81273902003-09-30 00:43:48 +00003519#endif /* LIBXML_READER_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003520 if (sax) {
3521 testSAX(argv[i]);
3522 } else {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003523 parseAndPrintFile(argv[i], NULL);
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003524 }
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003525
3526 if ((chkregister) && (nbregister != 0)) {
3527 fprintf(stderr, "Registration count off: %d\n", nbregister);
William M. Brack8304d872004-06-08 13:29:32 +00003528 progresult = XMLLINT_ERR_RDREGIS;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003529 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00003530 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003531 files ++;
Daniel Veillarda7866932001-12-04 13:14:44 +00003532 if ((timing) && (repeat)) {
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00003533 endTimer("%d iterations", repeat);
Daniel Veillarda7866932001-12-04 13:14:44 +00003534 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00003535 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003536 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00003537 if (generate)
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003538 parseAndPrintFile(NULL, NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003539 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003540 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003541 }
Daniel Veillard845cce42002-01-09 11:51:37 +00003542 if ((files == 0) && (!generate) && (version == 0)) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003543 usage(argv[0]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003544 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00003545#ifdef LIBXML_SCHEMATRON_ENABLED
3546 if (wxschematron != NULL)
3547 xmlSchematronFree(wxschematron);
3548#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00003549#ifdef LIBXML_SCHEMAS_ENABLED
3550 if (relaxngschemas != NULL)
3551 xmlRelaxNGFree(relaxngschemas);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003552 if (wxschemas != NULL)
3553 xmlSchemaFree(wxschemas);
Daniel Veillard71531f32003-02-05 13:19:53 +00003554 xmlRelaxNGCleanupTypes();
3555#endif
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003556#ifdef LIBXML_PATTERN_ENABLED
3557 if (patternc != NULL)
3558 xmlFreePattern(patternc);
3559#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003560 xmlCleanupParser();
3561 xmlMemoryDump();
3562
Daniel Veillardf7cd4812001-02-23 18:44:52 +00003563 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003564}
Daniel Veillard88a172f2000-08-04 18:23:10 +00003565