blob: ee41697d98369b02c93c657a9948f3364183450f [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 Veillard1df3dfc2001-12-18 11:14:16 +0000205
Daniel Veillard87076042004-05-03 22:54:49 +0000206/************************************************************************
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000207 * *
208 * Entity loading control and customization. *
209 * *
210 ************************************************************************/
211#define MAX_PATHS 64
Daniel Veillarded121382007-04-17 12:33:19 +0000212#ifdef _WIN32
213# define PATH_SEPARATOR ';'
214#else
215# define PATH_SEPARATOR ':'
216#endif
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000217static xmlChar *paths[MAX_PATHS + 1];
218static int nbpaths = 0;
219static int load_trace = 0;
220
221static
222void parsePath(const xmlChar *path) {
223 const xmlChar *cur;
224
225 if (path == NULL)
226 return;
227 while (*path != 0) {
228 if (nbpaths >= MAX_PATHS) {
229 fprintf(stderr, "MAX_PATHS reached: too many paths\n");
230 return;
231 }
232 cur = path;
Daniel Veillarded121382007-04-17 12:33:19 +0000233 while ((*cur == ' ') || (*cur == PATH_SEPARATOR))
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000234 cur++;
235 path = cur;
Daniel Veillarded121382007-04-17 12:33:19 +0000236 while ((*cur != 0) && (*cur != ' ') && (*cur != PATH_SEPARATOR))
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000237 cur++;
238 if (cur != path) {
239 paths[nbpaths] = xmlStrndup(path, cur - path);
240 if (paths[nbpaths] != NULL)
241 nbpaths++;
242 path = cur;
243 }
244 }
245}
246
Daniel Veillard24505b02005-07-28 23:49:35 +0000247static xmlExternalEntityLoader defaultEntityLoader = NULL;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000248
249static xmlParserInputPtr
250xmllintExternalEntityLoader(const char *URL, const char *ID,
251 xmlParserCtxtPtr ctxt) {
252 xmlParserInputPtr ret;
253 warningSAXFunc warning = NULL;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000254 errorSAXFunc err = NULL;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000255
256 int i;
257 const char *lastsegment = URL;
258 const char *iter = URL;
259
Daniel Veillard5608b172008-01-11 06:53:15 +0000260 if ((nbpaths > 0) && (iter != NULL)) {
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000261 while (*iter != 0) {
262 if (*iter == '/')
263 lastsegment = iter + 1;
264 iter++;
265 }
266 }
267
268 if ((ctxt != NULL) && (ctxt->sax != NULL)) {
269 warning = ctxt->sax->warning;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000270 err = ctxt->sax->error;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000271 ctxt->sax->warning = NULL;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000272 ctxt->sax->error = NULL;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000273 }
274
275 if (defaultEntityLoader != NULL) {
276 ret = defaultEntityLoader(URL, ID, ctxt);
277 if (ret != NULL) {
278 if (warning != NULL)
279 ctxt->sax->warning = warning;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000280 if (err != NULL)
281 ctxt->sax->error = err;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000282 if (load_trace) {
283 fprintf \
284 (stderr,
285 "Loaded URL=\"%s\" ID=\"%s\"\n",
286 URL ? URL : "(null)",
287 ID ? ID : "(null)");
288 }
289 return(ret);
290 }
291 }
292 for (i = 0;i < nbpaths;i++) {
293 xmlChar *newURL;
294
295 newURL = xmlStrdup((const xmlChar *) paths[i]);
296 newURL = xmlStrcat(newURL, (const xmlChar *) "/");
297 newURL = xmlStrcat(newURL, (const xmlChar *) lastsegment);
298 if (newURL != NULL) {
299 ret = defaultEntityLoader((const char *)newURL, ID, ctxt);
300 if (ret != NULL) {
301 if (warning != NULL)
302 ctxt->sax->warning = warning;
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000303 if (err != NULL)
304 ctxt->sax->error = err;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000305 if (load_trace) {
306 fprintf \
307 (stderr,
308 "Loaded URL=\"%s\" ID=\"%s\"\n",
309 newURL,
310 ID ? ID : "(null)");
311 }
312 xmlFree(newURL);
313 return(ret);
314 }
315 xmlFree(newURL);
316 }
317 }
Daniel Veillardea71f5d2006-02-19 16:55:55 +0000318 if (err != NULL)
319 ctxt->sax->error = err;
Daniel Veillard0bff36d2004-08-31 09:37:03 +0000320 if (warning != NULL) {
321 ctxt->sax->warning = warning;
322 if (URL != NULL)
323 warning(ctxt, "failed to load external entity \"%s\"\n", URL);
324 else if (ID != NULL)
325 warning(ctxt, "failed to load external entity \"%s\"\n", ID);
326 }
327 return(NULL);
328}
329/************************************************************************
Daniel Veillard87076042004-05-03 22:54:49 +0000330 * *
331 * Memory allocation consumption debugging *
332 * *
333 ************************************************************************/
334
Daniel Veillard3af3b592004-05-05 19:22:30 +0000335static void
336OOM(void)
337{
Daniel Veillard87076042004-05-03 22:54:49 +0000338 fprintf(stderr, "Ran out of memory needs > %d bytes\n", maxmem);
William M. Brack8304d872004-06-08 13:29:32 +0000339 progresult = XMLLINT_ERR_MEM;
Daniel Veillard87076042004-05-03 22:54:49 +0000340}
341
Daniel Veillard3af3b592004-05-05 19:22:30 +0000342static void
343myFreeFunc(void *mem)
344{
Daniel Veillard87076042004-05-03 22:54:49 +0000345 xmlMemFree(mem);
346}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000347static void *
348myMallocFunc(size_t size)
349{
Daniel Veillard87076042004-05-03 22:54:49 +0000350 void *ret;
351
352 ret = xmlMemMalloc(size);
353 if (ret != NULL) {
354 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000355 OOM();
356 xmlMemFree(ret);
357 return (NULL);
358 }
Daniel Veillard87076042004-05-03 22:54:49 +0000359 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000360 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000361}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000362static void *
363myReallocFunc(void *mem, size_t size)
364{
Daniel Veillard87076042004-05-03 22:54:49 +0000365 void *ret;
366
367 ret = xmlMemRealloc(mem, size);
368 if (ret != NULL) {
369 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000370 OOM();
371 xmlMemFree(ret);
372 return (NULL);
373 }
Daniel Veillard87076042004-05-03 22:54:49 +0000374 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000375 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000376}
Daniel Veillard3af3b592004-05-05 19:22:30 +0000377static char *
378myStrdupFunc(const char *str)
379{
Daniel Veillard87076042004-05-03 22:54:49 +0000380 char *ret;
381
382 ret = xmlMemoryStrdup(str);
383 if (ret != NULL) {
384 if (xmlMemUsed() > maxmem) {
Daniel Veillard3af3b592004-05-05 19:22:30 +0000385 OOM();
386 xmlFree(ret);
387 return (NULL);
388 }
Daniel Veillard87076042004-05-03 22:54:49 +0000389 }
Daniel Veillard3af3b592004-05-05 19:22:30 +0000390 return (ret);
Daniel Veillard87076042004-05-03 22:54:49 +0000391}
Daniel Veillard87076042004-05-03 22:54:49 +0000392/************************************************************************
393 * *
394 * Internal timing routines to remove the necessity to have *
395 * unix-specific function calls. *
396 * *
397 ************************************************************************/
Daniel Veillard01db67c2001-12-18 07:09:59 +0000398
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000399#ifndef HAVE_GETTIMEOFDAY
400#ifdef HAVE_SYS_TIMEB_H
401#ifdef HAVE_SYS_TIME_H
402#ifdef HAVE_FTIME
403
Daniel Veillard01c13b52002-12-10 15:19:08 +0000404static int
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000405my_gettimeofday(struct timeval *tvp, void *tzp)
406{
407 struct timeb timebuffer;
408
409 ftime(&timebuffer);
410 if (tvp) {
411 tvp->tv_sec = timebuffer.time;
412 tvp->tv_usec = timebuffer.millitm * 1000L;
413 }
414 return (0);
415}
416#define HAVE_GETTIMEOFDAY 1
417#define gettimeofday my_gettimeofday
418
419#endif /* HAVE_FTIME */
420#endif /* HAVE_SYS_TIME_H */
421#endif /* HAVE_SYS_TIMEB_H */
422#endif /* !HAVE_GETTIMEOFDAY */
423
Daniel Veillard01db67c2001-12-18 07:09:59 +0000424#if defined(HAVE_GETTIMEOFDAY)
425static struct timeval begin, end;
426
427/*
428 * startTimer: call where you want to start timing
429 */
430static void
431startTimer(void)
432{
433 gettimeofday(&begin, NULL);
434}
435
436/*
437 * endTimer: call where you want to stop timing and to print out a
438 * message about the timing performed; format is a printf
439 * type argument
440 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000441static void XMLCDECL
Daniel Veillard118aed72002-09-24 14:13:13 +0000442endTimer(const char *fmt, ...)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000443{
444 long msec;
445 va_list ap;
446
447 gettimeofday(&end, NULL);
448 msec = end.tv_sec - begin.tv_sec;
449 msec *= 1000;
450 msec += (end.tv_usec - begin.tv_usec) / 1000;
451
452#ifndef HAVE_STDARG_H
453#error "endTimer required stdarg functions"
454#endif
Daniel Veillard118aed72002-09-24 14:13:13 +0000455 va_start(ap, fmt);
456 vfprintf(stderr, fmt, ap);
Daniel Veillard01db67c2001-12-18 07:09:59 +0000457 va_end(ap);
458
459 fprintf(stderr, " took %ld ms\n", msec);
460}
461#elif defined(HAVE_TIME_H)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000462/*
463 * No gettimeofday function, so we have to make do with calling clock.
464 * This is obviously less accurate, but there's little we can do about
465 * that.
466 */
Daniel Veillard90bc3712002-03-07 15:12:58 +0000467#ifndef CLOCKS_PER_SEC
468#define CLOCKS_PER_SEC 100
469#endif
Daniel Veillard01db67c2001-12-18 07:09:59 +0000470
471static clock_t begin, end;
472static void
473startTimer(void)
474{
475 begin = clock();
476}
Daniel Veillardffa3c742005-07-21 13:24:09 +0000477static void XMLCDECL
Daniel Veillard01db67c2001-12-18 07:09:59 +0000478endTimer(const char *fmt, ...)
479{
480 long msec;
481 va_list ap;
482
483 end = clock();
484 msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
485
486#ifndef HAVE_STDARG_H
487#error "endTimer required stdarg functions"
488#endif
489 va_start(ap, fmt);
490 vfprintf(stderr, fmt, ap);
491 va_end(ap);
492 fprintf(stderr, " took %ld ms\n", msec);
493}
494#else
495
496/*
497 * We don't have a gettimeofday or time.h, so we just don't do timing
498 */
499static void
500startTimer(void)
501{
502 /*
503 * Do nothing
504 */
505}
Daniel Veillardffa3c742005-07-21 13:24:09 +0000506static void XMLCDECL
Daniel Veillard01db67c2001-12-18 07:09:59 +0000507endTimer(char *format, ...)
508{
509 /*
510 * We cannot do anything because we don't have a timing function
511 */
512#ifdef HAVE_STDARG_H
513 va_start(ap, format);
514 vfprintf(stderr, format, ap);
515 va_end(ap);
516 fprintf(stderr, " was not timed\n", msec);
517#else
518 /* We don't have gettimeofday, time or stdarg.h, what crazy world is
519 * this ?!
520 */
521#endif
522}
523#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000524/************************************************************************
525 * *
526 * HTML ouput *
527 * *
528 ************************************************************************/
Daniel Veillard24505b02005-07-28 23:49:35 +0000529static char buffer[50000];
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000530
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000531static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000532xmlHTMLEncodeSend(void) {
533 char *result;
534
535 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
536 if (result) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000537 xmlGenericError(xmlGenericErrorContext, "%s", result);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000538 xmlFree(result);
539 }
540 buffer[0] = 0;
541}
542
543/**
544 * xmlHTMLPrintFileInfo:
545 * @input: an xmlParserInputPtr input
546 *
547 * Displays the associated file and line informations for the current input
548 */
549
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000550static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000551xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000552 int len;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000553 xmlGenericError(xmlGenericErrorContext, "<p>");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000554
555 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000556 if (input != NULL) {
557 if (input->filename) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000558 snprintf(&buffer[len], sizeof(buffer) - len, "%s:%d: ", input->filename,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000559 input->line);
560 } else {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000561 snprintf(&buffer[len], sizeof(buffer) - len, "Entity: line %d: ", input->line);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000562 }
563 }
564 xmlHTMLEncodeSend();
565}
566
567/**
568 * xmlHTMLPrintFileContext:
569 * @input: an xmlParserInputPtr input
570 *
571 * Displays current context within the input content for error tracking
572 */
573
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000574static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000575xmlHTMLPrintFileContext(xmlParserInputPtr input) {
576 const xmlChar *cur, *base;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000577 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000578 int n;
579
580 if (input == NULL) return;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000581 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000582 cur = input->cur;
583 base = input->base;
584 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
585 cur--;
586 }
587 n = 0;
588 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
589 cur--;
590 if ((*cur == '\n') || (*cur == '\r')) cur++;
591 base = cur;
592 n = 0;
593 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000594 len = strlen(buffer);
595 snprintf(&buffer[len], sizeof(buffer) - len, "%c",
596 (unsigned char) *cur++);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000597 n++;
598 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000599 len = strlen(buffer);
600 snprintf(&buffer[len], sizeof(buffer) - len, "\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000601 cur = input->cur;
602 while ((*cur == '\n') || (*cur == '\r'))
603 cur--;
604 n = 0;
605 while ((cur != base) && (n++ < 80)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000606 len = strlen(buffer);
607 snprintf(&buffer[len], sizeof(buffer) - len, " ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000608 base++;
609 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000610 len = strlen(buffer);
611 snprintf(&buffer[len], sizeof(buffer) - len, "^\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000612 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000613 xmlGenericError(xmlGenericErrorContext, "</pre>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000614}
615
616/**
617 * xmlHTMLError:
618 * @ctx: an XML parser context
619 * @msg: the message to display/transmit
620 * @...: extra parameters for the message display
621 *
622 * Display and format an error messages, gives file, line, position and
623 * extra parameters.
624 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000625static void XMLCDECL
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000626xmlHTMLError(void *ctx, const char *msg, ...)
627{
628 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
629 xmlParserInputPtr input;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000630 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000631 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000632
633 buffer[0] = 0;
634 input = ctxt->input;
635 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000636 input = ctxt->inputTab[ctxt->inputNr - 2];
637 }
638
639 xmlHTMLPrintFileInfo(input);
640
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000641 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000642 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000643 len = strlen(buffer);
644 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000645 va_end(args);
646 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000647 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000648
649 xmlHTMLPrintFileContext(input);
650 xmlHTMLEncodeSend();
651}
652
653/**
654 * xmlHTMLWarning:
655 * @ctx: an XML parser context
656 * @msg: the message to display/transmit
657 * @...: extra parameters for the message display
658 *
659 * Display and format a warning messages, gives file, line, position and
660 * extra parameters.
661 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000662static void XMLCDECL
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000663xmlHTMLWarning(void *ctx, const char *msg, ...)
664{
665 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
666 xmlParserInputPtr input;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000667 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000668 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000669
670 buffer[0] = 0;
671 input = ctxt->input;
672 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000673 input = ctxt->inputTab[ctxt->inputNr - 2];
674 }
675
676
677 xmlHTMLPrintFileInfo(input);
678
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000679 xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000680 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000681 len = strlen(buffer);
682 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000683 va_end(args);
684 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000685 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000686
687 xmlHTMLPrintFileContext(input);
688 xmlHTMLEncodeSend();
689}
690
691/**
692 * xmlHTMLValidityError:
693 * @ctx: an XML parser context
694 * @msg: the message to display/transmit
695 * @...: extra parameters for the message display
696 *
697 * Display and format an validity error messages, gives file,
698 * line, position and extra parameters.
699 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000700static void XMLCDECL
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000701xmlHTMLValidityError(void *ctx, const char *msg, ...)
702{
703 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
704 xmlParserInputPtr input;
705 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000706 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000707
708 buffer[0] = 0;
709 input = ctxt->input;
710 if ((input->filename == NULL) && (ctxt->inputNr > 1))
711 input = ctxt->inputTab[ctxt->inputNr - 2];
712
713 xmlHTMLPrintFileInfo(input);
714
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000715 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000716 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000717 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000718 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000719 va_end(args);
720 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000721 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000722
723 xmlHTMLPrintFileContext(input);
724 xmlHTMLEncodeSend();
Daniel Veillard9fcb4912005-03-16 12:57:31 +0000725 progresult = XMLLINT_ERR_VALID;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000726}
727
728/**
729 * xmlHTMLValidityWarning:
730 * @ctx: an XML parser context
731 * @msg: the message to display/transmit
732 * @...: extra parameters for the message display
733 *
734 * Display and format a validity warning messages, gives file, line,
735 * position and extra parameters.
736 */
Daniel Veillardffa3c742005-07-21 13:24:09 +0000737static void XMLCDECL
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000738xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
739{
740 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
741 xmlParserInputPtr input;
742 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000743 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000744
745 buffer[0] = 0;
746 input = ctxt->input;
747 if ((input->filename == NULL) && (ctxt->inputNr > 1))
748 input = ctxt->inputTab[ctxt->inputNr - 2];
749
750 xmlHTMLPrintFileInfo(input);
751
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000752 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000753 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000754 len = strlen(buffer);
755 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000756 va_end(args);
757 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000758 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000759
760 xmlHTMLPrintFileContext(input);
761 xmlHTMLEncodeSend();
762}
763
764/************************************************************************
765 * *
766 * Shell Interface *
767 * *
768 ************************************************************************/
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000769#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000770#ifdef LIBXML_XPATH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000771/**
772 * xmlShellReadline:
773 * @prompt: the prompt value
774 *
775 * Read a string
776 *
777 * Returns a pointer to it or NULL on EOF the caller is expected to
778 * free the returned string.
779 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000780static char *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000781xmlShellReadline(char *prompt) {
782#ifdef HAVE_LIBREADLINE
783 char *line_read;
784
785 /* Get a line from the user. */
786 line_read = readline (prompt);
787
788 /* If the line has any text in it, save it on the history. */
789 if (line_read && *line_read)
790 add_history (line_read);
791
792 return (line_read);
793#else
794 char line_read[501];
Daniel Veillard29e43992001-12-13 22:21:58 +0000795 char *ret;
796 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000797
798 if (prompt != NULL)
799 fprintf(stdout, "%s", prompt);
800 if (!fgets(line_read, 500, stdin))
801 return(NULL);
802 line_read[500] = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000803 len = strlen(line_read);
804 ret = (char *) malloc(len + 1);
805 if (ret != NULL) {
806 memcpy (ret, line_read, len + 1);
807 }
808 return(ret);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000809#endif
810}
Daniel Veillardd0cf7f62004-11-09 16:17:02 +0000811#endif /* LIBXML_XPATH_ENABLED */
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000812#endif /* LIBXML_DEBUG_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000813
814/************************************************************************
815 * *
Daniel Veillard5e873c42000-04-12 13:27:38 +0000816 * I/O Interfaces *
817 * *
818 ************************************************************************/
819
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000820static int myRead(FILE *f, char * buf, int len) {
821 return(fread(buf, 1, len, f));
Daniel Veillard5e873c42000-04-12 13:27:38 +0000822}
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000823static void myClose(FILE *f) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000824 if (f != stdin) {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000825 fclose(f);
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000826 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000827}
828
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000829/************************************************************************
830 * *
831 * SAX based tests *
832 * *
833 ************************************************************************/
834
835/*
836 * empty SAX block
837 */
Daniel Veillard24505b02005-07-28 23:49:35 +0000838static xmlSAXHandler emptySAXHandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000839 NULL, /* internalSubset */
840 NULL, /* isStandalone */
841 NULL, /* hasInternalSubset */
842 NULL, /* hasExternalSubset */
843 NULL, /* resolveEntity */
844 NULL, /* getEntity */
845 NULL, /* entityDecl */
846 NULL, /* notationDecl */
847 NULL, /* attributeDecl */
848 NULL, /* elementDecl */
849 NULL, /* unparsedEntityDecl */
850 NULL, /* setDocumentLocator */
851 NULL, /* startDocument */
852 NULL, /* endDocument */
853 NULL, /* startElement */
854 NULL, /* endElement */
855 NULL, /* reference */
856 NULL, /* characters */
857 NULL, /* ignorableWhitespace */
858 NULL, /* processingInstruction */
859 NULL, /* comment */
860 NULL, /* xmlParserWarning */
861 NULL, /* xmlParserError */
862 NULL, /* xmlParserError */
863 NULL, /* getParameterEntity */
864 NULL, /* cdataBlock; */
865 NULL, /* externalSubset; */
Daniel Veillard971771e2005-07-09 17:32:57 +0000866 XML_SAX2_MAGIC,
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000867 NULL,
868 NULL, /* startElementNs */
869 NULL, /* endElementNs */
870 NULL /* xmlStructuredErrorFunc */
871};
872
Daniel Veillard24505b02005-07-28 23:49:35 +0000873static xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +0000874extern xmlSAXHandlerPtr debugSAXHandler;
875static int callbacks;
876
877/**
878 * isStandaloneDebug:
879 * @ctxt: An XML parser context
880 *
881 * Is this document tagged standalone ?
882 *
883 * Returns 1 if true
884 */
885static int
886isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
887{
888 callbacks++;
889 if (noout)
890 return(0);
891 fprintf(stdout, "SAX.isStandalone()\n");
892 return(0);
893}
894
895/**
896 * hasInternalSubsetDebug:
897 * @ctxt: An XML parser context
898 *
899 * Does this document has an internal subset
900 *
901 * Returns 1 if true
902 */
903static int
904hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
905{
906 callbacks++;
907 if (noout)
908 return(0);
909 fprintf(stdout, "SAX.hasInternalSubset()\n");
910 return(0);
911}
912
913/**
914 * hasExternalSubsetDebug:
915 * @ctxt: An XML parser context
916 *
917 * Does this document has an external subset
918 *
919 * Returns 1 if true
920 */
921static int
922hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
923{
924 callbacks++;
925 if (noout)
926 return(0);
927 fprintf(stdout, "SAX.hasExternalSubset()\n");
928 return(0);
929}
930
931/**
932 * internalSubsetDebug:
933 * @ctxt: An XML parser context
934 *
935 * Does this document has an internal subset
936 */
937static void
938internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
939 const xmlChar *ExternalID, const xmlChar *SystemID)
940{
941 callbacks++;
942 if (noout)
943 return;
944 fprintf(stdout, "SAX.internalSubset(%s,", name);
945 if (ExternalID == NULL)
946 fprintf(stdout, " ,");
947 else
948 fprintf(stdout, " %s,", ExternalID);
949 if (SystemID == NULL)
950 fprintf(stdout, " )\n");
951 else
952 fprintf(stdout, " %s)\n", SystemID);
953}
954
955/**
956 * externalSubsetDebug:
957 * @ctxt: An XML parser context
958 *
959 * Does this document has an external subset
960 */
961static void
962externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
963 const xmlChar *ExternalID, const xmlChar *SystemID)
964{
965 callbacks++;
966 if (noout)
967 return;
968 fprintf(stdout, "SAX.externalSubset(%s,", name);
969 if (ExternalID == NULL)
970 fprintf(stdout, " ,");
971 else
972 fprintf(stdout, " %s,", ExternalID);
973 if (SystemID == NULL)
974 fprintf(stdout, " )\n");
975 else
976 fprintf(stdout, " %s)\n", SystemID);
977}
978
979/**
980 * resolveEntityDebug:
981 * @ctxt: An XML parser context
982 * @publicId: The public ID of the entity
983 * @systemId: The system ID of the entity
984 *
985 * Special entity resolver, better left to the parser, it has
986 * more context than the application layer.
987 * The default behaviour is to NOT resolve the entities, in that case
988 * the ENTITY_REF nodes are built in the structure (and the parameter
989 * values).
990 *
991 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
992 */
993static xmlParserInputPtr
994resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
995{
996 callbacks++;
997 if (noout)
998 return(NULL);
999 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1000
1001
1002 fprintf(stdout, "SAX.resolveEntity(");
1003 if (publicId != NULL)
1004 fprintf(stdout, "%s", (char *)publicId);
1005 else
1006 fprintf(stdout, " ");
1007 if (systemId != NULL)
1008 fprintf(stdout, ", %s)\n", (char *)systemId);
1009 else
1010 fprintf(stdout, ", )\n");
1011 return(NULL);
1012}
1013
1014/**
1015 * getEntityDebug:
1016 * @ctxt: An XML parser context
1017 * @name: The entity name
1018 *
1019 * Get an entity by name
1020 *
1021 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
1022 */
1023static xmlEntityPtr
1024getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1025{
1026 callbacks++;
1027 if (noout)
1028 return(NULL);
1029 fprintf(stdout, "SAX.getEntity(%s)\n", name);
1030 return(NULL);
1031}
1032
1033/**
1034 * getParameterEntityDebug:
1035 * @ctxt: An XML parser context
1036 * @name: The entity name
1037 *
1038 * Get a parameter entity by name
1039 *
1040 * Returns the xmlParserInputPtr
1041 */
1042static xmlEntityPtr
1043getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1044{
1045 callbacks++;
1046 if (noout)
1047 return(NULL);
1048 fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
1049 return(NULL);
1050}
1051
1052
1053/**
1054 * entityDeclDebug:
1055 * @ctxt: An XML parser context
1056 * @name: the entity name
1057 * @type: the entity type
1058 * @publicId: The public ID of the entity
1059 * @systemId: The system ID of the entity
1060 * @content: the entity value (without processing).
1061 *
1062 * An entity definition has been parsed
1063 */
1064static void
1065entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
1066 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
1067{
1068const xmlChar *nullstr = BAD_CAST "(null)";
1069 /* not all libraries handle printing null pointers nicely */
1070 if (publicId == NULL)
1071 publicId = nullstr;
1072 if (systemId == NULL)
1073 systemId = nullstr;
1074 if (content == NULL)
1075 content = (xmlChar *)nullstr;
1076 callbacks++;
1077 if (noout)
1078 return;
1079 fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
1080 name, type, publicId, systemId, content);
1081}
1082
1083/**
1084 * attributeDeclDebug:
1085 * @ctxt: An XML parser context
1086 * @name: the attribute name
1087 * @type: the attribute type
1088 *
1089 * An attribute definition has been parsed
1090 */
1091static void
1092attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar * elem,
1093 const xmlChar * name, int type, int def,
1094 const xmlChar * defaultValue, xmlEnumerationPtr tree)
1095{
1096 callbacks++;
1097 if (noout)
1098 return;
1099 if (defaultValue == NULL)
1100 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
1101 elem, name, type, def);
1102 else
1103 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
1104 elem, name, type, def, defaultValue);
1105 xmlFreeEnumeration(tree);
1106}
1107
1108/**
1109 * elementDeclDebug:
1110 * @ctxt: An XML parser context
1111 * @name: the element name
1112 * @type: the element type
1113 * @content: the element value (without processing).
1114 *
1115 * An element definition has been parsed
1116 */
1117static void
1118elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
1119 xmlElementContentPtr content ATTRIBUTE_UNUSED)
1120{
1121 callbacks++;
1122 if (noout)
1123 return;
1124 fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
1125 name, type);
1126}
1127
1128/**
1129 * notationDeclDebug:
1130 * @ctxt: An XML parser context
1131 * @name: The name of the notation
1132 * @publicId: The public ID of the entity
1133 * @systemId: The system ID of the entity
1134 *
1135 * What to do when a notation declaration has been parsed.
1136 */
1137static void
1138notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
1139 const xmlChar *publicId, const xmlChar *systemId)
1140{
1141 callbacks++;
1142 if (noout)
1143 return;
1144 fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
1145 (char *) name, (char *) publicId, (char *) systemId);
1146}
1147
1148/**
1149 * unparsedEntityDeclDebug:
1150 * @ctxt: An XML parser context
1151 * @name: The name of the entity
1152 * @publicId: The public ID of the entity
1153 * @systemId: The system ID of the entity
1154 * @notationName: the name of the notation
1155 *
1156 * What to do when an unparsed entity declaration is parsed
1157 */
1158static void
1159unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
1160 const xmlChar *publicId, const xmlChar *systemId,
1161 const xmlChar *notationName)
1162{
1163const xmlChar *nullstr = BAD_CAST "(null)";
1164
1165 if (publicId == NULL)
1166 publicId = nullstr;
1167 if (systemId == NULL)
1168 systemId = nullstr;
1169 if (notationName == NULL)
1170 notationName = nullstr;
1171 callbacks++;
1172 if (noout)
1173 return;
1174 fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
1175 (char *) name, (char *) publicId, (char *) systemId,
1176 (char *) notationName);
1177}
1178
1179/**
1180 * setDocumentLocatorDebug:
1181 * @ctxt: An XML parser context
1182 * @loc: A SAX Locator
1183 *
1184 * Receive the document locator at startup, actually xmlDefaultSAXLocator
1185 * Everything is available on the context, so this is useless in our case.
1186 */
1187static void
1188setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
1189{
1190 callbacks++;
1191 if (noout)
1192 return;
1193 fprintf(stdout, "SAX.setDocumentLocator()\n");
1194}
1195
1196/**
1197 * startDocumentDebug:
1198 * @ctxt: An XML parser context
1199 *
1200 * called when the document start being processed.
1201 */
1202static void
1203startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
1204{
1205 callbacks++;
1206 if (noout)
1207 return;
1208 fprintf(stdout, "SAX.startDocument()\n");
1209}
1210
1211/**
1212 * endDocumentDebug:
1213 * @ctxt: An XML parser context
1214 *
1215 * called when the document end has been detected.
1216 */
1217static void
1218endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
1219{
1220 callbacks++;
1221 if (noout)
1222 return;
1223 fprintf(stdout, "SAX.endDocument()\n");
1224}
1225
1226/**
1227 * startElementDebug:
1228 * @ctxt: An XML parser context
1229 * @name: The element name
1230 *
1231 * called when an opening tag has been processed.
1232 */
1233static void
1234startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
1235{
1236 int i;
1237
1238 callbacks++;
1239 if (noout)
1240 return;
1241 fprintf(stdout, "SAX.startElement(%s", (char *) name);
1242 if (atts != NULL) {
1243 for (i = 0;(atts[i] != NULL);i++) {
1244 fprintf(stdout, ", %s='", atts[i++]);
1245 if (atts[i] != NULL)
1246 fprintf(stdout, "%s'", atts[i]);
1247 }
1248 }
1249 fprintf(stdout, ")\n");
1250}
1251
1252/**
1253 * endElementDebug:
1254 * @ctxt: An XML parser context
1255 * @name: The element name
1256 *
1257 * called when the end of an element has been detected.
1258 */
1259static void
1260endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1261{
1262 callbacks++;
1263 if (noout)
1264 return;
1265 fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
1266}
1267
1268/**
1269 * charactersDebug:
1270 * @ctxt: An XML parser context
1271 * @ch: a xmlChar string
1272 * @len: the number of xmlChar
1273 *
1274 * receiving some chars from the parser.
1275 * Question: how much at a time ???
1276 */
1277static void
1278charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
1279{
1280 char out[40];
1281 int i;
1282
1283 callbacks++;
1284 if (noout)
1285 return;
1286 for (i = 0;(i<len) && (i < 30);i++)
1287 out[i] = ch[i];
1288 out[i] = 0;
1289
1290 fprintf(stdout, "SAX.characters(%s, %d)\n", out, len);
1291}
1292
1293/**
1294 * referenceDebug:
1295 * @ctxt: An XML parser context
1296 * @name: The entity name
1297 *
1298 * called when an entity reference is detected.
1299 */
1300static void
1301referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1302{
1303 callbacks++;
1304 if (noout)
1305 return;
1306 fprintf(stdout, "SAX.reference(%s)\n", name);
1307}
1308
1309/**
1310 * ignorableWhitespaceDebug:
1311 * @ctxt: An XML parser context
1312 * @ch: a xmlChar string
1313 * @start: the first char in the string
1314 * @len: the number of xmlChar
1315 *
1316 * receiving some ignorable whitespaces from the parser.
1317 * Question: how much at a time ???
1318 */
1319static void
1320ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
1321{
1322 char out[40];
1323 int i;
1324
1325 callbacks++;
1326 if (noout)
1327 return;
1328 for (i = 0;(i<len) && (i < 30);i++)
1329 out[i] = ch[i];
1330 out[i] = 0;
1331 fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", out, len);
1332}
1333
1334/**
1335 * processingInstructionDebug:
1336 * @ctxt: An XML parser context
1337 * @target: the target name
1338 * @data: the PI data's
1339 * @len: the number of xmlChar
1340 *
1341 * A processing instruction has been parsed.
1342 */
1343static void
1344processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
1345 const xmlChar *data)
1346{
1347 callbacks++;
1348 if (noout)
1349 return;
1350 if (data != NULL)
1351 fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
1352 (char *) target, (char *) data);
1353 else
1354 fprintf(stdout, "SAX.processingInstruction(%s, NULL)\n",
1355 (char *) target);
1356}
1357
1358/**
1359 * cdataBlockDebug:
1360 * @ctx: the user data (XML parser context)
1361 * @value: The pcdata content
1362 * @len: the block length
1363 *
1364 * called when a pcdata block has been parsed
1365 */
1366static void
1367cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
1368{
1369 callbacks++;
1370 if (noout)
1371 return;
1372 fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
1373 (char *) value, len);
1374}
1375
1376/**
1377 * commentDebug:
1378 * @ctxt: An XML parser context
1379 * @value: the comment content
1380 *
1381 * A comment has been parsed.
1382 */
1383static void
1384commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
1385{
1386 callbacks++;
1387 if (noout)
1388 return;
1389 fprintf(stdout, "SAX.comment(%s)\n", value);
1390}
1391
1392/**
1393 * warningDebug:
1394 * @ctxt: An XML parser context
1395 * @msg: the message to display/transmit
1396 * @...: extra parameters for the message display
1397 *
1398 * Display and format a warning messages, gives file, line, position and
1399 * extra parameters.
1400 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001401static void XMLCDECL
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001402warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1403{
1404 va_list args;
1405
1406 callbacks++;
1407 if (noout)
1408 return;
1409 va_start(args, msg);
1410 fprintf(stdout, "SAX.warning: ");
1411 vfprintf(stdout, msg, args);
1412 va_end(args);
1413}
1414
1415/**
1416 * errorDebug:
1417 * @ctxt: An XML parser context
1418 * @msg: the message to display/transmit
1419 * @...: extra parameters for the message display
1420 *
1421 * Display and format a error messages, gives file, line, position and
1422 * extra parameters.
1423 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001424static void XMLCDECL
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001425errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1426{
1427 va_list args;
1428
1429 callbacks++;
1430 if (noout)
1431 return;
1432 va_start(args, msg);
1433 fprintf(stdout, "SAX.error: ");
1434 vfprintf(stdout, msg, args);
1435 va_end(args);
1436}
1437
1438/**
1439 * fatalErrorDebug:
1440 * @ctxt: An XML parser context
1441 * @msg: the message to display/transmit
1442 * @...: extra parameters for the message display
1443 *
1444 * Display and format a fatalError messages, gives file, line, position and
1445 * extra parameters.
1446 */
Daniel Veillardffa3c742005-07-21 13:24:09 +00001447static void XMLCDECL
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001448fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1449{
1450 va_list args;
1451
1452 callbacks++;
1453 if (noout)
1454 return;
1455 va_start(args, msg);
1456 fprintf(stdout, "SAX.fatalError: ");
1457 vfprintf(stdout, msg, args);
1458 va_end(args);
1459}
1460
Daniel Veillard24505b02005-07-28 23:49:35 +00001461static xmlSAXHandler debugSAXHandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001462 internalSubsetDebug,
1463 isStandaloneDebug,
1464 hasInternalSubsetDebug,
1465 hasExternalSubsetDebug,
1466 resolveEntityDebug,
1467 getEntityDebug,
1468 entityDeclDebug,
1469 notationDeclDebug,
1470 attributeDeclDebug,
1471 elementDeclDebug,
1472 unparsedEntityDeclDebug,
1473 setDocumentLocatorDebug,
1474 startDocumentDebug,
1475 endDocumentDebug,
1476 startElementDebug,
1477 endElementDebug,
1478 referenceDebug,
1479 charactersDebug,
1480 ignorableWhitespaceDebug,
1481 processingInstructionDebug,
1482 commentDebug,
1483 warningDebug,
1484 errorDebug,
1485 fatalErrorDebug,
1486 getParameterEntityDebug,
1487 cdataBlockDebug,
1488 externalSubsetDebug,
1489 1,
1490 NULL,
1491 NULL,
1492 NULL,
1493 NULL
1494};
1495
1496xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
1497
1498/*
1499 * SAX2 specific callbacks
1500 */
1501/**
1502 * startElementNsDebug:
1503 * @ctxt: An XML parser context
1504 * @name: The element name
1505 *
1506 * called when an opening tag has been processed.
1507 */
1508static void
1509startElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
1510 const xmlChar *localname,
1511 const xmlChar *prefix,
1512 const xmlChar *URI,
1513 int nb_namespaces,
1514 const xmlChar **namespaces,
1515 int nb_attributes,
1516 int nb_defaulted,
1517 const xmlChar **attributes)
1518{
1519 int i;
1520
1521 callbacks++;
1522 if (noout)
1523 return;
1524 fprintf(stdout, "SAX.startElementNs(%s", (char *) localname);
1525 if (prefix == NULL)
1526 fprintf(stdout, ", NULL");
1527 else
1528 fprintf(stdout, ", %s", (char *) prefix);
1529 if (URI == NULL)
1530 fprintf(stdout, ", NULL");
1531 else
1532 fprintf(stdout, ", '%s'", (char *) URI);
1533 fprintf(stdout, ", %d", nb_namespaces);
1534
1535 if (namespaces != NULL) {
1536 for (i = 0;i < nb_namespaces * 2;i++) {
1537 fprintf(stdout, ", xmlns");
1538 if (namespaces[i] != NULL)
1539 fprintf(stdout, ":%s", namespaces[i]);
1540 i++;
1541 fprintf(stdout, "='%s'", namespaces[i]);
1542 }
1543 }
1544 fprintf(stdout, ", %d, %d", nb_attributes, nb_defaulted);
1545 if (attributes != NULL) {
1546 for (i = 0;i < nb_attributes * 5;i += 5) {
1547 if (attributes[i + 1] != NULL)
1548 fprintf(stdout, ", %s:%s='", attributes[i + 1], attributes[i]);
1549 else
1550 fprintf(stdout, ", %s='", attributes[i]);
1551 fprintf(stdout, "%.4s...', %d", attributes[i + 3],
1552 (int)(attributes[i + 4] - attributes[i + 3]));
1553 }
1554 }
1555 fprintf(stdout, ")\n");
1556}
1557
1558/**
1559 * endElementDebug:
1560 * @ctxt: An XML parser context
1561 * @name: The element name
1562 *
1563 * called when the end of an element has been detected.
1564 */
1565static void
1566endElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
1567 const xmlChar *localname,
1568 const xmlChar *prefix,
1569 const xmlChar *URI)
1570{
1571 callbacks++;
1572 if (noout)
1573 return;
1574 fprintf(stdout, "SAX.endElementNs(%s", (char *) localname);
1575 if (prefix == NULL)
1576 fprintf(stdout, ", NULL");
1577 else
1578 fprintf(stdout, ", %s", (char *) prefix);
1579 if (URI == NULL)
1580 fprintf(stdout, ", NULL)\n");
1581 else
1582 fprintf(stdout, ", '%s')\n", (char *) URI);
1583}
1584
Daniel Veillard24505b02005-07-28 23:49:35 +00001585static xmlSAXHandler debugSAX2HandlerStruct = {
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001586 internalSubsetDebug,
1587 isStandaloneDebug,
1588 hasInternalSubsetDebug,
1589 hasExternalSubsetDebug,
1590 resolveEntityDebug,
1591 getEntityDebug,
1592 entityDeclDebug,
1593 notationDeclDebug,
1594 attributeDeclDebug,
1595 elementDeclDebug,
1596 unparsedEntityDeclDebug,
1597 setDocumentLocatorDebug,
1598 startDocumentDebug,
1599 endDocumentDebug,
1600 NULL,
1601 NULL,
1602 referenceDebug,
1603 charactersDebug,
1604 ignorableWhitespaceDebug,
1605 processingInstructionDebug,
1606 commentDebug,
1607 warningDebug,
1608 errorDebug,
1609 fatalErrorDebug,
1610 getParameterEntityDebug,
1611 cdataBlockDebug,
1612 externalSubsetDebug,
1613 XML_SAX2_MAGIC,
1614 NULL,
1615 startElementNsDebug,
1616 endElementNsDebug,
1617 NULL
1618};
1619
Daniel Veillard24505b02005-07-28 23:49:35 +00001620static xmlSAXHandlerPtr debugSAX2Handler = &debugSAX2HandlerStruct;
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001621
1622static void
1623testSAX(const char *filename) {
1624 xmlSAXHandlerPtr handler;
1625 const char *user_data = "user_data"; /* mostly for debugging */
1626 xmlParserInputBufferPtr buf = NULL;
1627 xmlParserInputPtr inputStream;
1628 xmlParserCtxtPtr ctxt = NULL;
1629 xmlSAXHandlerPtr old_sax = NULL;
1630
1631 callbacks = 0;
1632
1633 if (noout) {
1634 handler = emptySAXHandler;
Daniel Veillard78dfc9f2005-07-10 22:30:30 +00001635#ifdef LIBXML_SAX1_ENABLED
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001636 } else if (sax1) {
1637 handler = debugSAXHandler;
Daniel Veillard78dfc9f2005-07-10 22:30:30 +00001638#endif
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001639 } else {
1640 handler = debugSAX2Handler;
1641 }
1642
1643 /*
1644 * it's not the simplest code but the most generic in term of I/O
1645 */
1646 buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
1647 if (buf == NULL) {
1648 goto error;
1649 }
1650
1651#ifdef LIBXML_SCHEMAS_ENABLED
1652 if (wxschemas != NULL) {
1653 int ret;
1654 xmlSchemaValidCtxtPtr vctxt;
1655
1656 vctxt = xmlSchemaNewValidCtxt(wxschemas);
1657 xmlSchemaSetValidErrors(vctxt,
1658 (xmlSchemaValidityErrorFunc) fprintf,
1659 (xmlSchemaValidityWarningFunc) fprintf,
1660 stderr);
1661
Daniel Veillard971771e2005-07-09 17:32:57 +00001662 ret = xmlSchemaValidateStream(vctxt, buf, 0, handler,
1663 (void *)user_data);
1664 if (repeat == 0) {
1665 if (ret == 0) {
1666 fprintf(stderr, "%s validates\n", filename);
1667 } else if (ret > 0) {
1668 fprintf(stderr, "%s fails to validate\n", filename);
1669 progresult = XMLLINT_ERR_VALID;
1670 } else {
1671 fprintf(stderr, "%s validation generated an internal error\n",
1672 filename);
1673 progresult = XMLLINT_ERR_VALID;
1674 }
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001675 }
1676 xmlSchemaFreeValidCtxt(vctxt);
1677 } else
1678#endif
1679 {
1680 /*
1681 * Create the parser context amd hook the input
1682 */
1683 ctxt = xmlNewParserCtxt();
1684 if (ctxt == NULL) {
1685 xmlFreeParserInputBuffer(buf);
1686 goto error;
1687 }
1688 old_sax = ctxt->sax;
1689 ctxt->sax = handler;
1690 ctxt->userData = (void *) user_data;
1691 inputStream = xmlNewIOInputStream(ctxt, buf, XML_CHAR_ENCODING_NONE);
1692 if (inputStream == NULL) {
1693 xmlFreeParserInputBuffer(buf);
1694 goto error;
1695 }
1696 inputPush(ctxt, inputStream);
1697
1698 /* do the parsing */
1699 xmlParseDocument(ctxt);
1700
1701 if (ctxt->myDoc != NULL) {
1702 fprintf(stderr, "SAX generated a doc !\n");
1703 xmlFreeDoc(ctxt->myDoc);
1704 ctxt->myDoc = NULL;
1705 }
1706 }
1707
1708error:
1709 if (ctxt != NULL) {
1710 ctxt->sax = old_sax;
1711 xmlFreeParserCtxt(ctxt);
1712 }
1713}
1714
Daniel Veillard5e873c42000-04-12 13:27:38 +00001715/************************************************************************
1716 * *
Daniel Veillard7704fb12003-01-03 16:19:51 +00001717 * Stream Test processing *
1718 * *
1719 ************************************************************************/
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00001720#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00001721static void processNode(xmlTextReaderPtr reader) {
Daniel Veillard198c1bf2003-10-20 17:07:41 +00001722 const xmlChar *name, *value;
Daniel Veillard16ef8002005-01-31 00:27:50 +00001723 int type, empty;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001724
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001725 type = xmlTextReaderNodeType(reader);
Daniel Veillard16ef8002005-01-31 00:27:50 +00001726 empty = xmlTextReaderIsEmptyElement(reader);
Daniel Veillard99737f52003-03-22 14:55:50 +00001727
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001728 if (debug) {
1729 name = xmlTextReaderConstName(reader);
1730 if (name == NULL)
1731 name = BAD_CAST "--";
Daniel Veillard7704fb12003-01-03 16:19:51 +00001732
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001733 value = xmlTextReaderConstValue(reader);
1734
1735
1736 printf("%d %d %s %d %d",
1737 xmlTextReaderDepth(reader),
1738 type,
1739 name,
Daniel Veillard16ef8002005-01-31 00:27:50 +00001740 empty,
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001741 xmlTextReaderHasValue(reader));
1742 if (value == NULL)
1743 printf("\n");
1744 else {
1745 printf(" %s\n", value);
1746 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001747 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001748#ifdef LIBXML_PATTERN_ENABLED
1749 if (patternc) {
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001750 xmlChar *path = NULL;
1751 int match = -1;
1752
1753 if (type == XML_READER_TYPE_ELEMENT) {
1754 /* do the check only on element start */
1755 match = xmlPatternMatch(patternc, xmlTextReaderCurrentNode(reader));
1756
1757 if (match) {
1758 path = xmlGetNodePath(xmlTextReaderCurrentNode(reader));
1759 printf("Node %s matches pattern %s\n", path, pattern);
1760 }
1761 }
1762 if (patstream != NULL) {
1763 int ret;
1764
1765 if (type == XML_READER_TYPE_ELEMENT) {
1766 ret = xmlStreamPush(patstream,
1767 xmlTextReaderConstLocalName(reader),
1768 xmlTextReaderConstNamespaceUri(reader));
1769 if (ret < 0) {
1770 fprintf(stderr, "xmlStreamPush() failure\n");
1771 xmlFreeStreamCtxt(patstream);
1772 patstream = NULL;
1773 } else if (ret != match) {
1774 if (path == NULL) {
1775 path = xmlGetNodePath(
1776 xmlTextReaderCurrentNode(reader));
1777 }
1778 fprintf(stderr,
1779 "xmlPatternMatch and xmlStreamPush disagree\n");
1780 fprintf(stderr,
1781 " pattern %s node %s\n",
1782 pattern, path);
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001783 }
1784
1785
Daniel Veillard16ef8002005-01-31 00:27:50 +00001786 }
1787 if ((type == XML_READER_TYPE_END_ELEMENT) ||
1788 ((type == XML_READER_TYPE_ELEMENT) && (empty))) {
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001789 ret = xmlStreamPop(patstream);
1790 if (ret < 0) {
1791 fprintf(stderr, "xmlStreamPop() failure\n");
1792 xmlFreeStreamCtxt(patstream);
1793 patstream = NULL;
1794 }
1795 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001796 }
Daniel Veillardf9d16912005-01-30 22:36:30 +00001797 if (path != NULL)
1798 xmlFree(path);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001799 }
1800#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001801}
1802
1803static void streamFile(char *filename) {
1804 xmlTextReaderPtr reader;
1805 int ret;
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001806#ifdef HAVE_SYS_MMAN_H
1807 int fd = -1;
1808 struct stat info;
1809 const char *base = NULL;
1810 xmlParserInputBufferPtr input = NULL;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001811
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001812 if (memory) {
1813 if (stat(filename, &info) < 0)
1814 return;
1815 if ((fd = open(filename, O_RDONLY)) < 0)
1816 return;
1817 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
1818 if (base == (void *) MAP_FAILED)
1819 return;
1820
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001821 reader = xmlReaderForMemory(base, info.st_size, filename,
1822 NULL, options);
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001823 } else
1824#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001825 reader = xmlReaderForFile(filename, NULL, options);
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001826#ifdef LIBXML_PATTERN_ENABLED
Daniel Veillardd4301ab2005-02-03 22:24:10 +00001827 if (pattern != NULL) {
1828 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
1829 if (patternc == NULL) {
1830 xmlGenericError(xmlGenericErrorContext,
1831 "Pattern %s failed to compile\n", pattern);
1832 progresult = XMLLINT_ERR_SCHEMAPAT;
1833 pattern = NULL;
1834 }
1835 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001836 if (patternc != NULL) {
1837 patstream = xmlPatternGetStreamCtxt(patternc);
1838 if (patstream != NULL) {
1839 ret = xmlStreamPush(patstream, NULL, NULL);
1840 if (ret < 0) {
1841 fprintf(stderr, "xmlStreamPush() failure\n");
1842 xmlFreeStreamCtxt(patstream);
1843 patstream = NULL;
1844 }
1845 }
1846 }
1847#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001848
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001849
Daniel Veillard7704fb12003-01-03 16:19:51 +00001850 if (reader != NULL) {
Daniel Veillard4432df22003-09-28 18:58:27 +00001851#ifdef LIBXML_VALID_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00001852 if (valid)
1853 xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
Daniel Veillardce192eb2003-04-16 15:58:05 +00001854 else
Daniel Veillard4432df22003-09-28 18:58:27 +00001855#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardce192eb2003-04-16 15:58:05 +00001856 xmlTextReaderSetParserProp(reader, XML_PARSER_LOADDTD, 1);
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001857#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +00001858 if (relaxng != NULL) {
Daniel Veillard81514ba2003-09-16 23:17:26 +00001859 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001860 startTimer();
1861 }
1862 ret = xmlTextReaderRelaxNGValidate(reader, relaxng);
1863 if (ret < 0) {
1864 xmlGenericError(xmlGenericErrorContext,
1865 "Relax-NG schema %s failed to compile\n", relaxng);
William M. Brack8304d872004-06-08 13:29:32 +00001866 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillardce192eb2003-04-16 15:58:05 +00001867 relaxng = NULL;
1868 }
Daniel Veillard81514ba2003-09-16 23:17:26 +00001869 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001870 endTimer("Compiling the schemas");
1871 }
1872 }
Daniel Veillardf10ae122005-07-10 19:03:16 +00001873 if (schema != NULL) {
1874 if ((timing) && (!repeat)) {
1875 startTimer();
1876 }
1877 ret = xmlTextReaderSchemaValidate(reader, schema);
1878 if (ret < 0) {
1879 xmlGenericError(xmlGenericErrorContext,
1880 "XSD schema %s failed to compile\n", schema);
1881 progresult = XMLLINT_ERR_SCHEMACOMP;
1882 schema = NULL;
1883 }
1884 if ((timing) && (!repeat)) {
1885 endTimer("Compiling the schemas");
1886 }
1887 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001888#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001889
1890 /*
1891 * Process all nodes in sequence
1892 */
Daniel Veillard81514ba2003-09-16 23:17:26 +00001893 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +00001894 startTimer();
1895 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001896 ret = xmlTextReaderRead(reader);
1897 while (ret == 1) {
Daniel Veillardb3de70c2003-12-02 22:32:15 +00001898 if ((debug)
1899#ifdef LIBXML_PATTERN_ENABLED
1900 || (patternc)
1901#endif
1902 )
Daniel Veillard7704fb12003-01-03 16:19:51 +00001903 processNode(reader);
1904 ret = xmlTextReaderRead(reader);
1905 }
Daniel Veillard81514ba2003-09-16 23:17:26 +00001906 if ((timing) && (!repeat)) {
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001907#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf54cd532004-02-25 11:52:31 +00001908 if (relaxng != NULL)
Daniel Veillard49138f12004-02-19 12:58:36 +00001909 endTimer("Parsing and validating");
1910 else
Daniel Veillardf54cd532004-02-25 11:52:31 +00001911#endif
Daniel Veillard4432df22003-09-28 18:58:27 +00001912#ifdef LIBXML_VALID_ENABLED
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001913 if (valid)
Daniel Veillardce192eb2003-04-16 15:58:05 +00001914 endTimer("Parsing and validating");
1915 else
Daniel Veillard4432df22003-09-28 18:58:27 +00001916#endif
Daniel Veillardf54cd532004-02-25 11:52:31 +00001917 endTimer("Parsing");
Daniel Veillardce192eb2003-04-16 15:58:05 +00001918 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00001919
Daniel Veillard4432df22003-09-28 18:58:27 +00001920#ifdef LIBXML_VALID_ENABLED
Daniel Veillardf6bad792003-04-11 19:38:54 +00001921 if (valid) {
1922 if (xmlTextReaderIsValid(reader) != 1) {
1923 xmlGenericError(xmlGenericErrorContext,
1924 "Document %s does not validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001925 progresult = XMLLINT_ERR_VALID;
Daniel Veillardf6bad792003-04-11 19:38:54 +00001926 }
1927 }
Daniel Veillard4432df22003-09-28 18:58:27 +00001928#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001929#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf10ae122005-07-10 19:03:16 +00001930 if ((relaxng != NULL) || (schema != NULL)) {
Daniel Veillardf4e55762003-04-15 23:32:22 +00001931 if (xmlTextReaderIsValid(reader) != 1) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001932 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001933 progresult = XMLLINT_ERR_VALID;
Daniel Veillardf4e55762003-04-15 23:32:22 +00001934 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001935 fprintf(stderr, "%s validates\n", filename);
Daniel Veillardf4e55762003-04-15 23:32:22 +00001936 }
1937 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +00001938#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001939 /*
1940 * Done, cleanup and status
1941 */
1942 xmlFreeTextReader(reader);
1943 if (ret != 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00001944 fprintf(stderr, "%s : failed to parse\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001945 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001946 }
1947 } else {
1948 fprintf(stderr, "Unable to open %s\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00001949 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7704fb12003-01-03 16:19:51 +00001950 }
Daniel Veillard2fc6df92005-01-30 18:42:55 +00001951#ifdef LIBXML_PATTERN_ENABLED
1952 if (patstream != NULL) {
1953 xmlFreeStreamCtxt(patstream);
1954 patstream = NULL;
1955 }
1956#endif
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001957#ifdef HAVE_SYS_MMAN_H
1958 if (memory) {
1959 xmlFreeParserInputBuffer(input);
1960 munmap((char *) base, info.st_size);
1961 close(fd);
1962 }
1963#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +00001964}
Daniel Veillard7899c5c2003-11-03 12:31:38 +00001965
1966static void walkDoc(xmlDocPtr doc) {
1967 xmlTextReaderPtr reader;
1968 int ret;
1969
Daniel Veillardd4301ab2005-02-03 22:24:10 +00001970#ifdef LIBXML_PATTERN_ENABLED
1971 xmlNodePtr root;
1972 const xmlChar *namespaces[22];
1973 int i;
1974 xmlNsPtr ns;
1975
1976 root = xmlDocGetRootElement(doc);
1977 for (ns = root->nsDef, i = 0;ns != NULL && i < 20;ns=ns->next) {
1978 namespaces[i++] = ns->href;
1979 namespaces[i++] = ns->prefix;
1980 }
1981 namespaces[i++] = NULL;
1982 namespaces[i++] = NULL;
1983
1984 if (pattern != NULL) {
1985 patternc = xmlPatterncompile((const xmlChar *) pattern, doc->dict,
1986 0, &namespaces[0]);
1987 if (patternc == NULL) {
1988 xmlGenericError(xmlGenericErrorContext,
1989 "Pattern %s failed to compile\n", pattern);
1990 progresult = XMLLINT_ERR_SCHEMAPAT;
1991 pattern = NULL;
1992 }
1993 }
Daniel Veillard2b2e02d2005-02-05 23:20:22 +00001994 if (patternc != NULL) {
1995 patstream = xmlPatternGetStreamCtxt(patternc);
1996 if (patstream != NULL) {
1997 ret = xmlStreamPush(patstream, NULL, NULL);
1998 if (ret < 0) {
1999 fprintf(stderr, "xmlStreamPush() failure\n");
2000 xmlFreeStreamCtxt(patstream);
2001 patstream = NULL;
2002 }
2003 }
2004 }
Daniel Veillardd4301ab2005-02-03 22:24:10 +00002005#endif /* LIBXML_PATTERN_ENABLED */
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002006 reader = xmlReaderWalker(doc);
2007 if (reader != NULL) {
2008 if ((timing) && (!repeat)) {
2009 startTimer();
2010 }
2011 ret = xmlTextReaderRead(reader);
2012 while (ret == 1) {
Daniel Veillardb3de70c2003-12-02 22:32:15 +00002013 if ((debug)
2014#ifdef LIBXML_PATTERN_ENABLED
2015 || (patternc)
2016#endif
2017 )
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002018 processNode(reader);
2019 ret = xmlTextReaderRead(reader);
2020 }
2021 if ((timing) && (!repeat)) {
2022 endTimer("walking through the doc");
2023 }
2024 xmlFreeTextReader(reader);
2025 if (ret != 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002026 fprintf(stderr, "failed to walk through the doc\n");
William M. Brack8304d872004-06-08 13:29:32 +00002027 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002028 }
2029 } else {
2030 fprintf(stderr, "Failed to crate a reader from the document\n");
William M. Brack8304d872004-06-08 13:29:32 +00002031 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002032 }
Daniel Veillard2b2e02d2005-02-05 23:20:22 +00002033#ifdef LIBXML_PATTERN_ENABLED
2034 if (patstream != NULL) {
2035 xmlFreeStreamCtxt(patstream);
2036 patstream = NULL;
2037 }
2038#endif
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002039}
Daniel Veillard81273902003-09-30 00:43:48 +00002040#endif /* LIBXML_READER_ENABLED */
Daniel Veillard7704fb12003-01-03 16:19:51 +00002041
2042/************************************************************************
2043 * *
2044 * Tree Test processing *
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002045 * *
2046 ************************************************************************/
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002047static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
Daniel Veillard652327a2003-09-29 18:02:38 +00002048 xmlDocPtr doc = NULL;
2049#ifdef LIBXML_TREE_ENABLED
2050 xmlDocPtr tmp;
2051#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002052
Daniel Veillard48b2f892001-02-25 16:11:03 +00002053 if ((timing) && (!repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00002054 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002055
2056
Daniel Veillard652327a2003-09-29 18:02:38 +00002057#ifdef LIBXML_TREE_ENABLED
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002058 if (filename == NULL) {
2059 if (generate) {
2060 xmlNodePtr n;
2061
2062 doc = xmlNewDoc(BAD_CAST "1.0");
Daniel Veillard95ddcd32004-10-26 21:53:55 +00002063 n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002064 xmlNodeSetContent(n, BAD_CAST "abc");
2065 xmlDocSetRootElement(doc, n);
2066 }
2067 }
Daniel Veillard652327a2003-09-29 18:02:38 +00002068#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002069#ifdef LIBXML_HTML_ENABLED
Daniel Veillard73b013f2003-09-30 12:36:01 +00002070#ifdef LIBXML_PUSH_ENABLED
William M. Brack78637da2003-07-31 14:47:38 +00002071 else if ((html) && (push)) {
2072 FILE *f;
2073
William M. Brack3403add2004-06-27 02:07:51 +00002074#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2075 f = fopen(filename, "rb");
2076#else
2077 f = fopen(filename, "r");
2078#endif
William M. Brack78637da2003-07-31 14:47:38 +00002079 if (f != NULL) {
2080 int res, size = 3;
2081 char chars[4096];
2082 htmlParserCtxtPtr ctxt;
2083
2084 /* if (repeat) */
2085 size = 4096;
2086 res = fread(chars, 1, 4, f);
2087 if (res > 0) {
2088 ctxt = htmlCreatePushParserCtxt(NULL, NULL,
William M. Brack1d75c8a2003-10-27 13:48:16 +00002089 chars, res, filename, XML_CHAR_ENCODING_NONE);
William M. Brack78637da2003-07-31 14:47:38 +00002090 while ((res = fread(chars, 1, size, f)) > 0) {
2091 htmlParseChunk(ctxt, chars, res, 0);
2092 }
2093 htmlParseChunk(ctxt, chars, 0, 1);
2094 doc = ctxt->myDoc;
2095 htmlFreeParserCtxt(ctxt);
2096 }
2097 fclose(f);
2098 }
2099 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00002100#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002101#ifdef HAVE_SYS_MMAN_H
2102 else if ((html) && (memory)) {
2103 int fd;
2104 struct stat info;
2105 const char *base;
2106 if (stat(filename, &info) < 0)
2107 return;
2108 if ((fd = open(filename, O_RDONLY)) < 0)
2109 return;
2110 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
2111 if (base == (void *) MAP_FAILED)
2112 return;
2113
2114 doc = htmlReadMemory((char *) base, info.st_size, filename,
2115 NULL, options);
2116
2117 munmap((char *) base, info.st_size);
2118 close(fd);
2119 }
2120#endif
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002121 else if (html) {
Daniel Veillard9475a352003-09-26 12:47:50 +00002122 doc = htmlReadFile(filename, NULL, options);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002123 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002124#endif /* LIBXML_HTML_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00002125 else {
Daniel Veillard73b013f2003-09-30 12:36:01 +00002126#ifdef LIBXML_PUSH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002127 /*
2128 * build an XML tree from a string;
2129 */
2130 if (push) {
2131 FILE *f;
2132
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002133 /* '-' Usually means stdin -<sven@zen.org> */
2134 if ((filename[0] == '-') && (filename[1] == 0)) {
2135 f = stdin;
2136 } else {
William M. Brack3403add2004-06-27 02:07:51 +00002137#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2138 f = fopen(filename, "rb");
2139#else
2140 f = fopen(filename, "r");
2141#endif
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002142 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002143 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +00002144 int ret;
Daniel Veillarda880b122003-04-21 21:36:41 +00002145 int res, size = 1024;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002146 char chars[1024];
2147 xmlParserCtxtPtr ctxt;
2148
Daniel Veillarda880b122003-04-21 21:36:41 +00002149 /* if (repeat) size = 1024; */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002150 res = fread(chars, 1, 4, f);
2151 if (res > 0) {
2152 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
2153 chars, res, filename);
Daniel Veillard500a1de2004-03-22 15:22:58 +00002154 xmlCtxtUseOptions(ctxt, options);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002155 while ((res = fread(chars, 1, size, f)) > 0) {
2156 xmlParseChunk(ctxt, chars, res, 0);
2157 }
2158 xmlParseChunk(ctxt, chars, 0, 1);
2159 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +00002160 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002161 xmlFreeParserCtxt(ctxt);
Daniel Veillarde715dd22000-08-29 18:29:38 +00002162 if (!ret) {
2163 xmlFreeDoc(doc);
2164 doc = NULL;
2165 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002166 }
2167 }
Daniel Veillard73b013f2003-09-30 12:36:01 +00002168 } else
2169#endif /* LIBXML_PUSH_ENABLED */
2170 if (testIO) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002171 if ((filename[0] == '-') && (filename[1] == 0)) {
Daniel Veillard60942de2003-09-25 21:05:58 +00002172 doc = xmlReadFd(0, NULL, NULL, options);
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002173 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002174 FILE *f;
Daniel Veillard5e873c42000-04-12 13:27:38 +00002175
William M. Brack3403add2004-06-27 02:07:51 +00002176#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2177 f = fopen(filename, "rb");
2178#else
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002179 f = fopen(filename, "r");
William M. Brack3403add2004-06-27 02:07:51 +00002180#endif
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002181 if (f != NULL) {
2182 if (rectxt == NULL)
2183 doc = xmlReadIO((xmlInputReadCallback) myRead,
2184 (xmlInputCloseCallback) myClose, f,
Daniel Veillard60942de2003-09-25 21:05:58 +00002185 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002186 else
2187 doc = xmlCtxtReadIO(rectxt,
2188 (xmlInputReadCallback) myRead,
2189 (xmlInputCloseCallback) myClose, f,
Daniel Veillard60942de2003-09-25 21:05:58 +00002190 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002191 } else
Daniel Veillard5e873c42000-04-12 13:27:38 +00002192 doc = NULL;
Daniel Veillard5e873c42000-04-12 13:27:38 +00002193 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002194 } else if (htmlout) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002195 xmlParserCtxtPtr ctxt;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002196
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002197 if (rectxt == NULL)
2198 ctxt = xmlNewParserCtxt();
2199 else
2200 ctxt = rectxt;
Daniel Veillard88a172f2000-08-04 18:23:10 +00002201 if (ctxt == NULL) {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002202 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +00002203 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002204 ctxt->sax->error = xmlHTMLError;
2205 ctxt->sax->warning = xmlHTMLWarning;
2206 ctxt->vctxt.error = xmlHTMLValidityError;
2207 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002208
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002209 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002210
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002211 if (rectxt == NULL)
2212 xmlFreeParserCtxt(ctxt);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002213 }
Daniel Veillard46e370e2000-07-21 20:32:03 +00002214#ifdef HAVE_SYS_MMAN_H
2215 } else if (memory) {
2216 int fd;
2217 struct stat info;
2218 const char *base;
2219 if (stat(filename, &info) < 0)
2220 return;
2221 if ((fd = open(filename, O_RDONLY)) < 0)
2222 return;
2223 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillard29579362000-08-14 17:57:48 +00002224 if (base == (void *) MAP_FAILED)
Daniel Veillard46e370e2000-07-21 20:32:03 +00002225 return;
2226
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002227 if (rectxt == NULL)
Daniel Veillard60942de2003-09-25 21:05:58 +00002228 doc = xmlReadMemory((char *) base, info.st_size,
2229 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002230 else
Daniel Veillard60942de2003-09-25 21:05:58 +00002231 doc = xmlCtxtReadMemory(rectxt, (char *) base, info.st_size,
2232 filename, NULL, options);
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002233
Daniel Veillard46e370e2000-07-21 20:32:03 +00002234 munmap((char *) base, info.st_size);
Daniel Veillardf1a27c62006-10-13 22:33:03 +00002235 close(fd);
Daniel Veillard46e370e2000-07-21 20:32:03 +00002236#endif
Daniel Veillard4432df22003-09-28 18:58:27 +00002237#ifdef LIBXML_VALID_ENABLED
Daniel Veillardea7751d2002-12-20 00:16:24 +00002238 } else if (valid) {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002239 xmlParserCtxtPtr ctxt = NULL;
Daniel Veillardea7751d2002-12-20 00:16:24 +00002240
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002241 if (rectxt == NULL)
2242 ctxt = xmlNewParserCtxt();
2243 else
2244 ctxt = rectxt;
Daniel Veillardea7751d2002-12-20 00:16:24 +00002245 if (ctxt == NULL) {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002246 doc = NULL;
Daniel Veillardea7751d2002-12-20 00:16:24 +00002247 } else {
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002248 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
2249
2250 if (ctxt->valid == 0)
William M. Brack8304d872004-06-08 13:29:32 +00002251 progresult = XMLLINT_ERR_RDFILE;
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002252 if (rectxt == NULL)
2253 xmlFreeParserCtxt(ctxt);
Daniel Veillardea7751d2002-12-20 00:16:24 +00002254 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002255#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardea7751d2002-12-20 00:16:24 +00002256 } else {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002257 if (rectxt != NULL)
2258 doc = xmlCtxtReadFile(rectxt, filename, NULL, options);
Daniel Veillard81562d22005-06-15 13:27:56 +00002259 else {
2260#ifdef LIBXML_SAX1_ENABLED
2261 if (sax1)
2262 doc = xmlParseFile(filename);
2263 else
2264#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002265 doc = xmlReadFile(filename, NULL, options);
Daniel Veillard81562d22005-06-15 13:27:56 +00002266 }
Daniel Veillardea7751d2002-12-20 00:16:24 +00002267 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002268 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002269
Daniel Veillard88a172f2000-08-04 18:23:10 +00002270 /*
2271 * If we don't have a document we might as well give up. Do we
2272 * want an error message here? <sven@zen.org> */
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002273 if (doc == NULL) {
William M. Brack8304d872004-06-08 13:29:32 +00002274 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard88a172f2000-08-04 18:23:10 +00002275 return;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002276 }
2277
Daniel Veillard48b2f892001-02-25 16:11:03 +00002278 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002279 endTimer("Parsing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002280 }
2281
Daniel Veillard29e43992001-12-13 22:21:58 +00002282 /*
2283 * Remove DOCTYPE nodes
2284 */
2285 if (dropdtd) {
2286 xmlDtdPtr dtd;
2287
2288 dtd = xmlGetIntSubset(doc);
2289 if (dtd != NULL) {
2290 xmlUnlinkNode((xmlNodePtr)dtd);
2291 xmlFreeDtd(dtd);
2292 }
2293 }
2294
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002295#ifdef LIBXML_XINCLUDE_ENABLED
Daniel Veillard48b2f892001-02-25 16:11:03 +00002296 if (xinclude) {
2297 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002298 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002299 }
William M. Brack4e1c2db2005-02-11 10:58:55 +00002300 if (xmlXIncludeProcessFlags(doc, options) < 0)
2301 progresult = XMLLINT_ERR_UNCLASS;
Daniel Veillard48b2f892001-02-25 16:11:03 +00002302 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002303 endTimer("Xinclude processing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002304 }
2305 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00002306#endif
Daniel Veillard88a172f2000-08-04 18:23:10 +00002307
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002308#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00002309#ifdef LIBXML_XPATH_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002310 /*
Daniel Veillardcbaf3992001-12-31 16:16:02 +00002311 * shell interaction
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002312 */
Daniel Veillard26a45c82006-10-20 12:55:34 +00002313 if (shell) {
2314 xmlXPathOrderDocElems(doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002315 xmlShell(doc, filename, xmlShellReadline, stdout);
Daniel Veillard26a45c82006-10-20 12:55:34 +00002316 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002317#endif
Daniel Veillardd0cf7f62004-11-09 16:17:02 +00002318#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002319
Daniel Veillard652327a2003-09-29 18:02:38 +00002320#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002321 /*
2322 * test intermediate copy if needed.
2323 */
2324 if (copy) {
2325 tmp = doc;
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002326 if (timing) {
2327 startTimer();
2328 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002329 doc = xmlCopyDoc(doc, 1);
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002330 if (timing) {
2331 endTimer("Copying");
2332 }
2333 if (timing) {
2334 startTimer();
2335 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002336 xmlFreeDoc(tmp);
Daniel Veillard4edd3ed2004-09-20 20:03:01 +00002337 if (timing) {
2338 endTimer("Freeing original");
2339 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002340 }
Daniel Veillard652327a2003-09-29 18:02:38 +00002341#endif /* LIBXML_TREE_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002342
Daniel Veillard4432df22003-09-28 18:58:27 +00002343#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002344 if ((insert) && (!html)) {
2345 const xmlChar* list[256];
2346 int nb, i;
2347 xmlNodePtr node;
2348
2349 if (doc->children != NULL) {
2350 node = doc->children;
2351 while ((node != NULL) && (node->last == NULL)) node = node->next;
2352 if (node != NULL) {
2353 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
2354 if (nb < 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002355 fprintf(stderr, "could not get valid list of elements\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002356 } else if (nb == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002357 fprintf(stderr, "No element can be inserted under root\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002358 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002359 fprintf(stderr, "%d element types can be inserted under root:\n",
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002360 nb);
2361 for (i = 0;i < nb;i++) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002362 fprintf(stderr, "%s\n", (char *) list[i]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002363 }
2364 }
2365 }
2366 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002367 }else
2368#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002369#ifdef LIBXML_READER_ENABLED
2370 if (walker) {
2371 walkDoc(doc);
2372 }
2373#endif /* LIBXML_READER_ENABLED */
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002374#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard4432df22003-09-28 18:58:27 +00002375 if (noout == 0) {
Daniel Veillard3df01182003-12-10 10:17:51 +00002376 int ret;
2377
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002378 /*
2379 * print it.
2380 */
2381#ifdef LIBXML_DEBUG_ENABLED
2382 if (!debug) {
2383#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00002384 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002385 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002386 }
Daniel Veillard656ce942004-04-30 23:11:45 +00002387#ifdef LIBXML_HTML_ENABLED
Daniel Veillard42fd4122003-11-04 08:47:48 +00002388 if ((html) && (!xmlout)) {
2389 if (compress) {
2390 htmlSaveFile(output ? output : "-", doc);
2391 }
2392 else if (encoding != NULL) {
2393 if ( format ) {
2394 htmlSaveFileFormat(output ? output : "-", doc, encoding, 1);
2395 }
2396 else {
2397 htmlSaveFileFormat(output ? output : "-", doc, encoding, 0);
2398 }
2399 }
2400 else if (format) {
2401 htmlSaveFileFormat(output ? output : "-", doc, NULL, 1);
2402 }
2403 else {
2404 FILE *out;
2405 if (output == NULL)
2406 out = stdout;
2407 else {
2408 out = fopen(output,"wb");
2409 }
2410 if (out != NULL) {
2411 if (htmlDocDump(out, doc) < 0)
William M. Brack8304d872004-06-08 13:29:32 +00002412 progresult = XMLLINT_ERR_OUT;
Daniel Veillard42fd4122003-11-04 08:47:48 +00002413
2414 if (output != NULL)
2415 fclose(out);
2416 } else {
2417 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00002418 progresult = XMLLINT_ERR_OUT;
Daniel Veillard42fd4122003-11-04 08:47:48 +00002419 }
2420 }
2421 if ((timing) && (!repeat)) {
2422 endTimer("Saving");
2423 }
2424 } else
2425#endif
Daniel Veillard25048d82004-08-14 22:37:54 +00002426#ifdef LIBXML_C14N_ENABLED
2427 if (canonical) {
2428 xmlChar *result = NULL;
2429 int size;
2430
2431 size = xmlC14NDocDumpMemory(doc, NULL, 0, NULL, 1, &result);
2432 if (size >= 0) {
2433 write(1, result, size);
2434 xmlFree(result);
2435 } else {
2436 fprintf(stderr, "Failed to canonicalize\n");
2437 progresult = XMLLINT_ERR_OUT;
2438 }
2439 } else
Aleksey Sanin2650df12005-06-06 17:16:50 +00002440 if (exc_canonical) {
2441 xmlChar *result = NULL;
2442 int size;
2443
2444 size = xmlC14NDocDumpMemory(doc, NULL, 1, NULL, 1, &result);
2445 if (size >= 0) {
2446 write(1, result, size);
2447 xmlFree(result);
2448 } else {
2449 fprintf(stderr, "Failed to canonicalize\n");
2450 progresult = XMLLINT_ERR_OUT;
2451 }
2452 } else
Daniel Veillard25048d82004-08-14 22:37:54 +00002453#endif
Daniel Veillard3b2c2612001-04-04 00:09:00 +00002454#ifdef HAVE_SYS_MMAN_H
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002455 if (memory) {
2456 xmlChar *result;
2457 int len;
2458
2459 if (encoding != NULL) {
Daniel Veillardd536f702001-11-08 17:32:47 +00002460 if ( format ) {
2461 xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
2462 } else {
2463 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
2464 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002465 } else {
Daniel Veillard90493a92001-08-14 14:12:47 +00002466 if (format)
2467 xmlDocDumpFormatMemory(doc, &result, &len, 1);
2468 else
2469 xmlDocDumpMemory(doc, &result, &len);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002470 }
2471 if (result == NULL) {
2472 fprintf(stderr, "Failed to save\n");
Daniel Veillard25048d82004-08-14 22:37:54 +00002473 progresult = XMLLINT_ERR_OUT;
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002474 } else {
2475 write(1, result, len);
2476 xmlFree(result);
2477 }
Daniel Veillarddab39b52006-10-16 23:22:10 +00002478
Daniel Veillard3b2c2612001-04-04 00:09:00 +00002479 } else
2480#endif /* HAVE_SYS_MMAN_H */
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002481 if (compress) {
2482 xmlSaveFile(output ? output : "-", doc);
Daniel Veillarddab39b52006-10-16 23:22:10 +00002483 } else if (oldout) {
2484 if (encoding != NULL) {
2485 if ( format ) {
2486 ret = xmlSaveFormatFileEnc(output ? output : "-", doc,
2487 encoding, 1);
2488 }
2489 else {
2490 ret = xmlSaveFileEnc(output ? output : "-", doc,
2491 encoding);
2492 }
2493 if (ret < 0) {
2494 fprintf(stderr, "failed save to %s\n",
2495 output ? output : "-");
2496 progresult = XMLLINT_ERR_OUT;
2497 }
2498 } else if (format) {
2499 ret = xmlSaveFormatFile(output ? output : "-", doc, 1);
2500 if (ret < 0) {
2501 fprintf(stderr, "failed save to %s\n",
2502 output ? output : "-");
2503 progresult = XMLLINT_ERR_OUT;
2504 }
Daniel Veillard05d987b2003-10-08 11:54:57 +00002505 } else {
Daniel Veillarddab39b52006-10-16 23:22:10 +00002506 FILE *out;
2507 if (output == NULL)
2508 out = stdout;
2509 else {
2510 out = fopen(output,"wb");
2511 }
2512 if (out != NULL) {
2513 if (xmlDocDump(out, doc) < 0)
2514 progresult = XMLLINT_ERR_OUT;
2515
2516 if (output != NULL)
2517 fclose(out);
2518 } else {
2519 fprintf(stderr, "failed to open %s\n", output);
2520 progresult = XMLLINT_ERR_OUT;
2521 }
2522 }
2523 } else {
2524 xmlSaveCtxtPtr ctxt;
2525 int saveOpts = 0;
2526
2527 if (format)
2528 saveOpts |= XML_SAVE_FORMAT;
2529
2530 if (output == NULL)
2531 ctxt = xmlSaveToFd(1, encoding, saveOpts);
2532 else
2533 ctxt = xmlSaveToFilename(output, encoding, saveOpts);
2534
2535 if (ctxt != NULL) {
2536 if (xmlSaveDoc(ctxt, doc) < 0) {
2537 fprintf(stderr, "failed save to %s\n",
2538 output ? output : "-");
2539 progresult = XMLLINT_ERR_OUT;
2540 }
2541 xmlSaveClose(ctxt);
2542 } else {
William M. Brack8304d872004-06-08 13:29:32 +00002543 progresult = XMLLINT_ERR_OUT;
Daniel Veillard05d987b2003-10-08 11:54:57 +00002544 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002545 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002546 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002547 endTimer("Saving");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002548 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002549#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002550 } else {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002551 FILE *out;
2552 if (output == NULL)
2553 out = stdout;
2554 else {
2555 out = fopen(output,"wb");
2556 }
Daniel Veillard05d987b2003-10-08 11:54:57 +00002557 if (out != NULL) {
2558 xmlDebugDumpDocument(out, doc);
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002559
Daniel Veillard05d987b2003-10-08 11:54:57 +00002560 if (output != NULL)
2561 fclose(out);
2562 } else {
2563 fprintf(stderr, "failed to open %s\n", output);
William M. Brack8304d872004-06-08 13:29:32 +00002564 progresult = XMLLINT_ERR_OUT;
Daniel Veillard05d987b2003-10-08 11:54:57 +00002565 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00002566 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002567#endif
2568 }
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002569#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002570
Daniel Veillard4432df22003-09-28 18:58:27 +00002571#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002572 /*
2573 * A posteriori validation test
2574 */
Daniel Veillard66f68e72003-08-18 16:39:51 +00002575 if ((dtdvalid != NULL) || (dtdvalidfpi != NULL)) {
Daniel Veillardcd429612000-10-11 15:57:05 +00002576 xmlDtdPtr dtd;
2577
Daniel Veillard48b2f892001-02-25 16:11:03 +00002578 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002579 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002580 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00002581 if (dtdvalid != NULL)
2582 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
2583 else
2584 dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL);
Daniel Veillard48b2f892001-02-25 16:11:03 +00002585 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002586 endTimer("Parsing DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002587 }
Daniel Veillardcd429612000-10-11 15:57:05 +00002588 if (dtd == NULL) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00002589 if (dtdvalid != NULL)
2590 xmlGenericError(xmlGenericErrorContext,
2591 "Could not parse DTD %s\n", dtdvalid);
2592 else
2593 xmlGenericError(xmlGenericErrorContext,
2594 "Could not parse DTD %s\n", dtdvalidfpi);
William M. Brack8304d872004-06-08 13:29:32 +00002595 progresult = XMLLINT_ERR_DTD;
Daniel Veillardcd429612000-10-11 15:57:05 +00002596 } else {
Daniel Veillarda37aab82003-06-09 09:10:36 +00002597 xmlValidCtxtPtr cvp;
2598
2599 if ((cvp = xmlNewValidCtxt()) == NULL) {
2600 xmlGenericError(xmlGenericErrorContext,
2601 "Couldn't allocate validation context\n");
2602 exit(-1);
2603 }
2604 cvp->userData = (void *) stderr;
2605 cvp->error = (xmlValidityErrorFunc) fprintf;
2606 cvp->warning = (xmlValidityWarningFunc) fprintf;
2607
Daniel Veillard48b2f892001-02-25 16:11:03 +00002608 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002609 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002610 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002611 if (!xmlValidateDtd(cvp, doc, dtd)) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00002612 if (dtdvalid != NULL)
2613 xmlGenericError(xmlGenericErrorContext,
2614 "Document %s does not validate against %s\n",
2615 filename, dtdvalid);
2616 else
2617 xmlGenericError(xmlGenericErrorContext,
2618 "Document %s does not validate against %s\n",
2619 filename, dtdvalidfpi);
William M. Brack8304d872004-06-08 13:29:32 +00002620 progresult = XMLLINT_ERR_VALID;
Daniel Veillardcd429612000-10-11 15:57:05 +00002621 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002622 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002623 endTimer("Validating against DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002624 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002625 xmlFreeValidCtxt(cvp);
Daniel Veillardcd429612000-10-11 15:57:05 +00002626 xmlFreeDtd(dtd);
2627 }
2628 } else if (postvalid) {
Daniel Veillarda37aab82003-06-09 09:10:36 +00002629 xmlValidCtxtPtr cvp;
2630
2631 if ((cvp = xmlNewValidCtxt()) == NULL) {
2632 xmlGenericError(xmlGenericErrorContext,
2633 "Couldn't allocate validation context\n");
2634 exit(-1);
2635 }
2636
Daniel Veillard48b2f892001-02-25 16:11:03 +00002637 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002638 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002639 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002640 cvp->userData = (void *) stderr;
2641 cvp->error = (xmlValidityErrorFunc) fprintf;
2642 cvp->warning = (xmlValidityWarningFunc) fprintf;
2643 if (!xmlValidateDocument(cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00002644 xmlGenericError(xmlGenericErrorContext,
2645 "Document %s does not validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002646 progresult = XMLLINT_ERR_VALID;
Daniel Veillardcd429612000-10-11 15:57:05 +00002647 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00002648 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002649 endTimer("Validating");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002650 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00002651 xmlFreeValidCtxt(cvp);
Daniel Veillard4432df22003-09-28 18:58:27 +00002652 }
2653#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardd4501d72005-07-24 14:27:16 +00002654#ifdef LIBXML_SCHEMATRON_ENABLED
2655 if (wxschematron != NULL) {
2656 xmlSchematronValidCtxtPtr ctxt;
2657 int ret;
Daniel Veillardc740a172005-07-31 12:17:24 +00002658 int flag;
Daniel Veillardd4501d72005-07-24 14:27:16 +00002659
2660 if ((timing) && (!repeat)) {
2661 startTimer();
2662 }
2663
2664 if (debug)
2665 flag = XML_SCHEMATRON_OUT_XML;
Daniel Veillardc740a172005-07-31 12:17:24 +00002666 else
2667 flag = XML_SCHEMATRON_OUT_TEXT;
2668 if (noout)
2669 flag |= XML_SCHEMATRON_OUT_QUIET;
Daniel Veillardd4501d72005-07-24 14:27:16 +00002670 ctxt = xmlSchematronNewValidCtxt(wxschematron, flag);
2671#if 0
2672 xmlSchematronSetValidErrors(ctxt,
2673 (xmlSchematronValidityErrorFunc) fprintf,
2674 (xmlSchematronValidityWarningFunc) fprintf,
2675 stderr);
2676#endif
2677 ret = xmlSchematronValidateDoc(ctxt, doc);
2678 if (ret == 0) {
2679 fprintf(stderr, "%s validates\n", filename);
2680 } else if (ret > 0) {
2681 fprintf(stderr, "%s fails to validate\n", filename);
2682 progresult = XMLLINT_ERR_VALID;
2683 } else {
2684 fprintf(stderr, "%s validation generated an internal error\n",
2685 filename);
2686 progresult = XMLLINT_ERR_VALID;
2687 }
2688 xmlSchematronFreeValidCtxt(ctxt);
2689 if ((timing) && (!repeat)) {
2690 endTimer("Validating");
2691 }
2692 }
2693#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00002694#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard4432df22003-09-28 18:58:27 +00002695 if (relaxngschemas != NULL) {
Daniel Veillard71531f32003-02-05 13:19:53 +00002696 xmlRelaxNGValidCtxtPtr ctxt;
2697 int ret;
2698
Daniel Veillard42f12e92003-03-07 18:32:59 +00002699 if ((timing) && (!repeat)) {
2700 startTimer();
2701 }
2702
Daniel Veillard71531f32003-02-05 13:19:53 +00002703 ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
2704 xmlRelaxNGSetValidErrors(ctxt,
2705 (xmlRelaxNGValidityErrorFunc) fprintf,
2706 (xmlRelaxNGValidityWarningFunc) fprintf,
2707 stderr);
2708 ret = xmlRelaxNGValidateDoc(ctxt, doc);
2709 if (ret == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002710 fprintf(stderr, "%s validates\n", filename);
Daniel Veillard71531f32003-02-05 13:19:53 +00002711 } else if (ret > 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002712 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002713 progresult = XMLLINT_ERR_VALID;
Daniel Veillard71531f32003-02-05 13:19:53 +00002714 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002715 fprintf(stderr, "%s validation generated an internal error\n",
Daniel Veillard71531f32003-02-05 13:19:53 +00002716 filename);
William M. Brack8304d872004-06-08 13:29:32 +00002717 progresult = XMLLINT_ERR_VALID;
Daniel Veillard71531f32003-02-05 13:19:53 +00002718 }
2719 xmlRelaxNGFreeValidCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00002720 if ((timing) && (!repeat)) {
2721 endTimer("Validating");
2722 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002723 } else if (wxschemas != NULL) {
2724 xmlSchemaValidCtxtPtr ctxt;
2725 int ret;
2726
2727 if ((timing) && (!repeat)) {
2728 startTimer();
2729 }
2730
2731 ctxt = xmlSchemaNewValidCtxt(wxschemas);
2732 xmlSchemaSetValidErrors(ctxt,
2733 (xmlSchemaValidityErrorFunc) fprintf,
2734 (xmlSchemaValidityWarningFunc) fprintf,
2735 stderr);
2736 ret = xmlSchemaValidateDoc(ctxt, doc);
2737 if (ret == 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002738 fprintf(stderr, "%s validates\n", filename);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002739 } else if (ret > 0) {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002740 fprintf(stderr, "%s fails to validate\n", filename);
William M. Brack8304d872004-06-08 13:29:32 +00002741 progresult = XMLLINT_ERR_VALID;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002742 } else {
Daniel Veillardd21f61b2003-12-29 10:31:21 +00002743 fprintf(stderr, "%s validation generated an internal error\n",
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002744 filename);
William M. Brack8304d872004-06-08 13:29:32 +00002745 progresult = XMLLINT_ERR_VALID;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002746 }
2747 xmlSchemaFreeValidCtxt(ctxt);
2748 if ((timing) && (!repeat)) {
2749 endTimer("Validating");
2750 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002751 }
Daniel Veillard4432df22003-09-28 18:58:27 +00002752#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002753
2754#ifdef LIBXML_DEBUG_ENABLED
2755 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00002756 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002757#endif
2758
2759 /*
2760 * free it.
2761 */
Daniel Veillard48b2f892001-02-25 16:11:03 +00002762 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002763 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00002764 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002765 xmlFreeDoc(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +00002766 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00002767 endTimer("Freeing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00002768 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002769}
2770
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002771/************************************************************************
2772 * *
2773 * Usage and Main *
2774 * *
2775 ************************************************************************/
2776
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002777static void showVersion(const char *name) {
2778 fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
2779 fprintf(stderr, " compiled with: ");
Daniel Veillard602434d2005-09-12 09:20:31 +00002780 if (xmlHasFeature(XML_WITH_THREAD)) fprintf(stderr, "Threads ");
2781 if (xmlHasFeature(XML_WITH_TREE)) fprintf(stderr, "Tree ");
2782 if (xmlHasFeature(XML_WITH_OUTPUT)) fprintf(stderr, "Output ");
2783 if (xmlHasFeature(XML_WITH_PUSH)) fprintf(stderr, "Push ");
2784 if (xmlHasFeature(XML_WITH_READER)) fprintf(stderr, "Reader ");
2785 if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(stderr, "Patterns ");
2786 if (xmlHasFeature(XML_WITH_WRITER)) fprintf(stderr, "Writer ");
2787 if (xmlHasFeature(XML_WITH_SAX1)) fprintf(stderr, "SAXv1 ");
2788 if (xmlHasFeature(XML_WITH_FTP)) fprintf(stderr, "FTP ");
2789 if (xmlHasFeature(XML_WITH_HTTP)) fprintf(stderr, "HTTP ");
2790 if (xmlHasFeature(XML_WITH_VALID)) fprintf(stderr, "DTDValid ");
2791 if (xmlHasFeature(XML_WITH_HTML)) fprintf(stderr, "HTML ");
2792 if (xmlHasFeature(XML_WITH_LEGACY)) fprintf(stderr, "Legacy ");
2793 if (xmlHasFeature(XML_WITH_C14N)) fprintf(stderr, "C14N ");
2794 if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(stderr, "Catalog ");
2795 if (xmlHasFeature(XML_WITH_XPATH)) fprintf(stderr, "XPath ");
2796 if (xmlHasFeature(XML_WITH_XPTR)) fprintf(stderr, "XPointer ");
2797 if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(stderr, "XInclude ");
2798 if (xmlHasFeature(XML_WITH_ICONV)) fprintf(stderr, "Iconv ");
2799 if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(stderr, "ISO8859X ");
2800 if (xmlHasFeature(XML_WITH_UNICODE)) fprintf(stderr, "Unicode ");
2801 if (xmlHasFeature(XML_WITH_REGEXP)) fprintf(stderr, "Regexps ");
2802 if (xmlHasFeature(XML_WITH_AUTOMATA)) fprintf(stderr, "Automata ");
2803 if (xmlHasFeature(XML_WITH_EXPR)) fprintf(stderr, "Expr ");
2804 if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(stderr, "Schemas ");
2805 if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(stderr, "Schematron ");
2806 if (xmlHasFeature(XML_WITH_MODULES)) fprintf(stderr, "Modules ");
2807 if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(stderr, "Debug ");
2808 if (xmlHasFeature(XML_WITH_DEBUG_MEM)) fprintf(stderr, "MemDebug ");
2809 if (xmlHasFeature(XML_WITH_DEBUG_RUN)) fprintf(stderr, "RunDebug ");
Daniel Veillard75acfee2006-07-13 06:29:56 +00002810 if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(stderr, "Zlib ");
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002811 fprintf(stderr, "\n");
2812}
2813
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002814static void usage(const char *name) {
2815 printf("Usage : %s [options] XMLfiles ...\n", name);
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002816#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002817 printf("\tParse the XML files and output the result of the parsing\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002818#else
2819 printf("\tParse the XML files\n");
2820#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002821 printf("\t--version : display the version of the XML library used\n");
2822#ifdef LIBXML_DEBUG_ENABLED
2823 printf("\t--debug : dump a debug tree of the in-memory document\n");
2824 printf("\t--shell : run a navigating shell\n");
2825 printf("\t--debugent : debug the entities defined in the document\n");
Daniel Veillard8326e732003-01-07 00:19:07 +00002826#else
Daniel Veillard81273902003-09-30 00:43:48 +00002827#ifdef LIBXML_READER_ENABLED
Daniel Veillard8326e732003-01-07 00:19:07 +00002828 printf("\t--debug : dump the nodes content when using --stream\n");
Daniel Veillard81273902003-09-30 00:43:48 +00002829#endif /* LIBXML_READER_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002830#endif
Daniel Veillard652327a2003-09-29 18:02:38 +00002831#ifdef LIBXML_TREE_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002832 printf("\t--copy : used to test the internal copy implementation\n");
Daniel Veillard652327a2003-09-29 18:02:38 +00002833#endif /* LIBXML_TREE_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002834 printf("\t--recover : output what was parsable on broken XML documents\n");
2835 printf("\t--noent : substitute entity references by their value\n");
2836 printf("\t--noout : don't output the result tree\n");
Daniel Veillard0bff36d2004-08-31 09:37:03 +00002837 printf("\t--path 'paths': provide a set of paths for resources\n");
2838 printf("\t--load-trace : print trace of all external entites loaded\n");
Daniel Veillarde8b09e42003-05-13 22:14:13 +00002839 printf("\t--nonet : refuse to fetch DTDs or entities over network\n");
Daniel Veillard8874b942005-08-25 13:19:21 +00002840 printf("\t--nocompact : do not generate compact text nodes\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002841 printf("\t--htmlout : output results as HTML\n");
Daniel Veillard05c13a22001-09-09 08:38:09 +00002842 printf("\t--nowrap : do not put HTML doc wrapper\n");
Daniel Veillard4432df22003-09-28 18:58:27 +00002843#ifdef LIBXML_VALID_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002844 printf("\t--valid : validate the document in addition to std well-formed check\n");
2845 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
2846 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
Daniel Veillard66f68e72003-08-18 16:39:51 +00002847 printf("\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
Daniel Veillard4432df22003-09-28 18:58:27 +00002848#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002849 printf("\t--timing : print some timings\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002850 printf("\t--output file or -o file: save to a given file\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002851 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
2852 printf("\t--insert : ad-hoc test for valid insertions\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002853#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002854#ifdef HAVE_ZLIB_H
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002855 printf("\t--compress : turn on gzip compression of output\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002856#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002857#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002858#ifdef LIBXML_HTML_ENABLED
2859 printf("\t--html : use the HTML parser\n");
Daniel Veillard42fd4122003-11-04 08:47:48 +00002860 printf("\t--xmlout : force to use the XML serializer when using --html\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002861#endif
Daniel Veillard73b013f2003-09-30 12:36:01 +00002862#ifdef LIBXML_PUSH_ENABLED
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002863 printf("\t--push : use the push mode of the parser\n");
Daniel Veillard73b013f2003-09-30 12:36:01 +00002864#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002865#ifdef HAVE_SYS_MMAN_H
2866 printf("\t--memory : parse from memory\n");
2867#endif
Daniel Veillard87076042004-05-03 22:54:49 +00002868 printf("\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002869 printf("\t--nowarning : do not emit warnings from parser/validator\n");
2870 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
Daniel Veillarddca8cc72003-09-26 13:53:14 +00002871 printf("\t--nocdata : replace cdata section with text nodes\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002872#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard90493a92001-08-14 14:12:47 +00002873 printf("\t--format : reformat/reindent the input\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002874 printf("\t--encode encoding : output in the given encoding\n");
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002875 printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
2876#endif /* LIBXML_OUTPUT_ENABLED */
Aleksey Sanin2650df12005-06-06 17:16:50 +00002877 printf("\t--c14n : save in W3C canonical format (with comments)\n");
2878 printf("\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n");
Daniel Veillard25048d82004-08-14 22:37:54 +00002879#ifdef LIBXML_C14N_ENABLED
2880#endif /* LIBXML_C14N_ENABLED */
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002881 printf("\t--nsclean : remove redundant namespace declarations\n");
2882 printf("\t--testIO : test user I/O support\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002883#ifdef LIBXML_CATALOG_ENABLED
Daniel Veillardbd9b0e82001-11-26 10:32:08 +00002884 printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
2885 printf("\t otherwise XML Catalogs starting from \n");
Daniel Veillardb3de70c2003-12-02 22:32:15 +00002886 printf("\t %s are activated by default\n", XML_XML_DEFAULT_CATALOG);
Daniel Veillard05c13a22001-09-09 08:38:09 +00002887 printf("\t--nocatalogs: deactivate all catalogs\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002888#endif
2889 printf("\t--auto : generate a small doc on the fly\n");
2890#ifdef LIBXML_XINCLUDE_ENABLED
2891 printf("\t--xinclude : do XInclude processing\n");
Daniel Veillardc14c3892004-08-16 12:34:50 +00002892 printf("\t--noxincludenode : same but do not generate XInclude nodes\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002893#endif
Daniel Veillardcbaf3992001-12-31 16:16:02 +00002894 printf("\t--loaddtd : fetch external DTD\n");
Daniel Veillard48da9102001-08-07 01:10:10 +00002895 printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
Daniel Veillard81273902003-09-30 00:43:48 +00002896#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00002897 printf("\t--stream : use the streaming interface to process very large files\n");
Daniel Veillard7899c5c2003-11-03 12:31:38 +00002898 printf("\t--walker : create a reader and walk though the resulting doc\n");
Daniel Veillard81273902003-09-30 00:43:48 +00002899#endif /* LIBXML_READER_ENABLED */
Daniel Veillardb3de70c2003-12-02 22:32:15 +00002900#ifdef LIBXML_PATTERN_ENABLED
2901 printf("\t--pattern pattern_value : test the pattern support\n");
2902#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00002903 printf("\t--chkregister : verify the node registration code\n");
Daniel Veillardef4d3bc2003-02-07 12:38:22 +00002904#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard71531f32003-02-05 13:19:53 +00002905 printf("\t--relaxng schema : do RelaxNG validation against the schema\n");
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00002906 printf("\t--schema schema : do validation against the WXS schema\n");
Daniel Veillard71531f32003-02-05 13:19:53 +00002907#endif
Daniel Veillarde70375c2005-07-30 21:09:12 +00002908#ifdef LIBXML_SCHEMATRON_ENABLED
2909 printf("\t--schematron schema : do validation against a schematron\n");
2910#endif
Daniel Veillard971771e2005-07-09 17:32:57 +00002911#ifdef LIBXML_SAX1_ENABLED
2912 printf("\t--sax1: use the old SAX1 interfaces for processing\n");
2913#endif
2914 printf("\t--sax: do not build a tree but work just at the SAX level\n");
2915
Daniel Veillarda42f25f2002-01-25 14:15:40 +00002916 printf("\nLibxml project home page: http://xmlsoft.org/\n");
2917 printf("To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002918}
Daniel Veillard8a1b1852003-01-05 22:37:17 +00002919
2920static void registerNode(xmlNodePtr node)
2921{
2922 node->_private = malloc(sizeof(long));
2923 *(long*)node->_private = (long) 0x81726354;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00002924 nbregister++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00002925}
2926
2927static void deregisterNode(xmlNodePtr node)
2928{
2929 assert(node->_private != NULL);
2930 assert(*(long*)node->_private == (long) 0x81726354);
2931 free(node->_private);
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00002932 nbregister--;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00002933}
2934
Daniel Veillard4a6845d2001-01-03 13:32:39 +00002935int
2936main(int argc, char **argv) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00002937 int i, acount;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002938 int files = 0;
Daniel Veillard845cce42002-01-09 11:51:37 +00002939 int version = 0;
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00002940 const char* indent;
2941
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002942 if (argc <= 1) {
2943 usage(argv[0]);
2944 return(1);
2945 }
Daniel Veillardbe803962000-06-28 23:40:59 +00002946 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002947 for (i = 1; i < argc ; i++) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00002948 if (!strcmp(argv[i], "-"))
2949 break;
2950
2951 if (argv[i][0] != '-')
2952 continue;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002953 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
2954 debug++;
Daniel Veillard56ada1d2003-01-07 11:17:25 +00002955 else
2956#ifdef LIBXML_DEBUG_ENABLED
2957 if ((!strcmp(argv[i], "-shell")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002958 (!strcmp(argv[i], "--shell"))) {
2959 shell++;
2960 noout = 1;
2961 } else
2962#endif
Daniel Veillard652327a2003-09-29 18:02:38 +00002963#ifdef LIBXML_TREE_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002964 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
2965 copy++;
Daniel Veillard652327a2003-09-29 18:02:38 +00002966 else
2967#endif /* LIBXML_TREE_ENABLED */
2968 if ((!strcmp(argv[i], "-recover")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002969 (!strcmp(argv[i], "--recover"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002970 recovery++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002971 options |= XML_PARSE_RECOVER;
2972 } else if ((!strcmp(argv[i], "-noent")) ||
2973 (!strcmp(argv[i], "--noent"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002974 noent++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002975 options |= XML_PARSE_NOENT;
Daniel Veillarddca8cc72003-09-26 13:53:14 +00002976 } else if ((!strcmp(argv[i], "-nsclean")) ||
2977 (!strcmp(argv[i], "--nsclean"))) {
2978 options |= XML_PARSE_NSCLEAN;
2979 } else if ((!strcmp(argv[i], "-nocdata")) ||
2980 (!strcmp(argv[i], "--nocdata"))) {
2981 options |= XML_PARSE_NOCDATA;
Daniel Veillarde96a2a42003-09-24 21:23:56 +00002982 } else if ((!strcmp(argv[i], "-nodict")) ||
2983 (!strcmp(argv[i], "--nodict"))) {
2984 options |= XML_PARSE_NODICT;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00002985 } else if ((!strcmp(argv[i], "-version")) ||
Daniel Veillard845cce42002-01-09 11:51:37 +00002986 (!strcmp(argv[i], "--version"))) {
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00002987 showVersion(argv[0]);
Daniel Veillard845cce42002-01-09 11:51:37 +00002988 version = 1;
2989 } else if ((!strcmp(argv[i], "-noout")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00002990 (!strcmp(argv[i], "--noout")))
2991 noout++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002992#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002993 else if ((!strcmp(argv[i], "-o")) ||
2994 (!strcmp(argv[i], "-output")) ||
2995 (!strcmp(argv[i], "--output"))) {
2996 i++;
Daniel Veillard6e4f1c02002-04-09 09:55:20 +00002997 output = argv[i];
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00002998 }
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00002999#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003000 else if ((!strcmp(argv[i], "-htmlout")) ||
3001 (!strcmp(argv[i], "--htmlout")))
3002 htmlout++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003003 else if ((!strcmp(argv[i], "-nowrap")) ||
3004 (!strcmp(argv[i], "--nowrap")))
3005 nowrap++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003006#ifdef LIBXML_HTML_ENABLED
3007 else if ((!strcmp(argv[i], "-html")) ||
3008 (!strcmp(argv[i], "--html"))) {
3009 html++;
3010 }
Daniel Veillard42fd4122003-11-04 08:47:48 +00003011 else if ((!strcmp(argv[i], "-xmlout")) ||
3012 (!strcmp(argv[i], "--xmlout"))) {
3013 xmlout++;
3014 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003015#endif /* LIBXML_HTML_ENABLED */
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003016 else if ((!strcmp(argv[i], "-loaddtd")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003017 (!strcmp(argv[i], "--loaddtd"))) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003018 loaddtd++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003019 options |= XML_PARSE_DTDLOAD;
3020 } else if ((!strcmp(argv[i], "-dtdattr")) ||
Daniel Veillard48da9102001-08-07 01:10:10 +00003021 (!strcmp(argv[i], "--dtdattr"))) {
3022 loaddtd++;
3023 dtdattrs++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003024 options |= XML_PARSE_DTDATTR;
Daniel Veillard4432df22003-09-28 18:58:27 +00003025 }
3026#ifdef LIBXML_VALID_ENABLED
3027 else if ((!strcmp(argv[i], "-valid")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003028 (!strcmp(argv[i], "--valid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003029 valid++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003030 options |= XML_PARSE_DTDVALID;
3031 } else if ((!strcmp(argv[i], "-postvalid")) ||
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003032 (!strcmp(argv[i], "--postvalid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003033 postvalid++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003034 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003035 options |= XML_PARSE_DTDLOAD;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003036 } else if ((!strcmp(argv[i], "-dtdvalid")) ||
Daniel Veillardcd429612000-10-11 15:57:05 +00003037 (!strcmp(argv[i], "--dtdvalid"))) {
3038 i++;
3039 dtdvalid = argv[i];
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003040 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003041 options |= XML_PARSE_DTDLOAD;
Daniel Veillard66f68e72003-08-18 16:39:51 +00003042 } else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3043 (!strcmp(argv[i], "--dtdvalidfpi"))) {
3044 i++;
3045 dtdvalidfpi = argv[i];
3046 loaddtd++;
Daniel Veillard5a30b2d2003-12-09 13:54:39 +00003047 options |= XML_PARSE_DTDLOAD;
Daniel Veillardcd429612000-10-11 15:57:05 +00003048 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003049#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard29e43992001-12-13 22:21:58 +00003050 else if ((!strcmp(argv[i], "-dropdtd")) ||
3051 (!strcmp(argv[i], "--dropdtd")))
3052 dropdtd++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003053 else if ((!strcmp(argv[i], "-insert")) ||
3054 (!strcmp(argv[i], "--insert")))
3055 insert++;
Daniel Veillard48b2f892001-02-25 16:11:03 +00003056 else if ((!strcmp(argv[i], "-timing")) ||
3057 (!strcmp(argv[i], "--timing")))
3058 timing++;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00003059 else if ((!strcmp(argv[i], "-auto")) ||
3060 (!strcmp(argv[i], "--auto")))
3061 generate++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003062 else if ((!strcmp(argv[i], "-repeat")) ||
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00003063 (!strcmp(argv[i], "--repeat"))) {
3064 if (repeat)
3065 repeat *= 10;
3066 else
3067 repeat = 100;
Daniel Veillard73b013f2003-09-30 12:36:01 +00003068 }
3069#ifdef LIBXML_PUSH_ENABLED
3070 else if ((!strcmp(argv[i], "-push")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003071 (!strcmp(argv[i], "--push")))
3072 push++;
Daniel Veillard73b013f2003-09-30 12:36:01 +00003073#endif /* LIBXML_PUSH_ENABLED */
Daniel Veillard46e370e2000-07-21 20:32:03 +00003074#ifdef HAVE_SYS_MMAN_H
3075 else if ((!strcmp(argv[i], "-memory")) ||
3076 (!strcmp(argv[i], "--memory")))
3077 memory++;
3078#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +00003079 else if ((!strcmp(argv[i], "-testIO")) ||
3080 (!strcmp(argv[i], "--testIO")))
3081 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003082#ifdef LIBXML_XINCLUDE_ENABLED
3083 else if ((!strcmp(argv[i], "-xinclude")) ||
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003084 (!strcmp(argv[i], "--xinclude"))) {
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003085 xinclude++;
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003086 options |= XML_PARSE_XINCLUDE;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003087 }
Daniel Veillardc14c3892004-08-16 12:34:50 +00003088 else if ((!strcmp(argv[i], "-noxincludenode")) ||
3089 (!strcmp(argv[i], "--noxincludenode"))) {
3090 xinclude++;
3091 options |= XML_PARSE_XINCLUDE;
3092 options |= XML_PARSE_NOXINCNODE;
3093 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00003094#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003095#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003096#ifdef HAVE_ZLIB_H
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003097 else if ((!strcmp(argv[i], "-compress")) ||
3098 (!strcmp(argv[i], "--compress"))) {
3099 compress++;
3100 xmlSetCompressMode(9);
3101 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003102#endif
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003103#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003104 else if ((!strcmp(argv[i], "-nowarning")) ||
3105 (!strcmp(argv[i], "--nowarning"))) {
3106 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003107 xmlPedanticParserDefault(0);
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003108 options |= XML_PARSE_NOWARNING;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003109 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003110 else if ((!strcmp(argv[i], "-pedantic")) ||
3111 (!strcmp(argv[i], "--pedantic"))) {
3112 xmlGetWarningsDefaultValue = 1;
3113 xmlPedanticParserDefault(1);
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003114 options |= XML_PARSE_PEDANTIC;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003115 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00003116#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003117 else if ((!strcmp(argv[i], "-debugent")) ||
3118 (!strcmp(argv[i], "--debugent"))) {
3119 debugent++;
3120 xmlParserDebugEntities = 1;
3121 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00003122#endif
Daniel Veillard25048d82004-08-14 22:37:54 +00003123#ifdef LIBXML_C14N_ENABLED
3124 else if ((!strcmp(argv[i], "-c14n")) ||
3125 (!strcmp(argv[i], "--c14n"))) {
3126 canonical++;
3127 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
3128 }
Aleksey Sanin2650df12005-06-06 17:16:50 +00003129 else if ((!strcmp(argv[i], "-exc-c14n")) ||
3130 (!strcmp(argv[i], "--exc-c14n"))) {
3131 exc_canonical++;
3132 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
3133 }
Daniel Veillard25048d82004-08-14 22:37:54 +00003134#endif
Daniel Veillard81418e32001-05-22 15:08:55 +00003135#ifdef LIBXML_CATALOG_ENABLED
3136 else if ((!strcmp(argv[i], "-catalogs")) ||
3137 (!strcmp(argv[i], "--catalogs"))) {
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003138 catalogs++;
3139 } else if ((!strcmp(argv[i], "-nocatalogs")) ||
3140 (!strcmp(argv[i], "--nocatalogs"))) {
3141 nocatalogs++;
Daniel Veillard81418e32001-05-22 15:08:55 +00003142 }
3143#endif
Daniel Veillardbe803962000-06-28 23:40:59 +00003144 else if ((!strcmp(argv[i], "-encode")) ||
3145 (!strcmp(argv[i], "--encode"))) {
3146 i++;
3147 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00003148 /*
3149 * OK it's for testing purposes
3150 */
3151 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +00003152 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003153 else if ((!strcmp(argv[i], "-noblanks")) ||
3154 (!strcmp(argv[i], "--noblanks"))) {
3155 noblanks++;
3156 xmlKeepBlanksDefault(0);
Daniel Veillard90493a92001-08-14 14:12:47 +00003157 }
Daniel Veillard87076042004-05-03 22:54:49 +00003158 else if ((!strcmp(argv[i], "-maxmem")) ||
3159 (!strcmp(argv[i], "--maxmem"))) {
3160 i++;
3161 if (sscanf(argv[i], "%d", &maxmem) == 1) {
3162 xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc,
3163 myStrdupFunc);
3164 } else {
3165 maxmem = 0;
3166 }
3167 }
Daniel Veillard90493a92001-08-14 14:12:47 +00003168 else if ((!strcmp(argv[i], "-format")) ||
3169 (!strcmp(argv[i], "--format"))) {
3170 noblanks++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003171#ifdef LIBXML_OUTPUT_ENABLED
Daniel Veillard90493a92001-08-14 14:12:47 +00003172 format++;
Daniel Veillarda9cce9c2003-09-29 13:20:24 +00003173#endif /* LIBXML_OUTPUT_ENABLED */
Daniel Veillard90493a92001-08-14 14:12:47 +00003174 xmlKeepBlanksDefault(0);
Daniel Veillard7704fb12003-01-03 16:19:51 +00003175 }
Daniel Veillard81273902003-09-30 00:43:48 +00003176#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003177 else if ((!strcmp(argv[i], "-stream")) ||
3178 (!strcmp(argv[i], "--stream"))) {
3179 stream++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003180 }
Daniel Veillard7899c5c2003-11-03 12:31:38 +00003181 else if ((!strcmp(argv[i], "-walker")) ||
3182 (!strcmp(argv[i], "--walker"))) {
3183 walker++;
3184 noout++;
3185 }
Daniel Veillard81273902003-09-30 00:43:48 +00003186#endif /* LIBXML_READER_ENABLED */
3187#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +00003188 else if ((!strcmp(argv[i], "-sax1")) ||
3189 (!strcmp(argv[i], "--sax1"))) {
3190 sax1++;
3191 }
Daniel Veillard81273902003-09-30 00:43:48 +00003192#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003193 else if ((!strcmp(argv[i], "-sax")) ||
3194 (!strcmp(argv[i], "--sax"))) {
3195 sax++;
3196 }
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003197 else if ((!strcmp(argv[i], "-chkregister")) ||
3198 (!strcmp(argv[i], "--chkregister"))) {
3199 chkregister++;
Daniel Veillard71531f32003-02-05 13:19:53 +00003200#ifdef LIBXML_SCHEMAS_ENABLED
3201 } else if ((!strcmp(argv[i], "-relaxng")) ||
3202 (!strcmp(argv[i], "--relaxng"))) {
3203 i++;
3204 relaxng = argv[i];
3205 noent++;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003206 options |= XML_PARSE_NOENT;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003207 } else if ((!strcmp(argv[i], "-schema")) ||
3208 (!strcmp(argv[i], "--schema"))) {
3209 i++;
3210 schema = argv[i];
3211 noent++;
Daniel Veillard71531f32003-02-05 13:19:53 +00003212#endif
Daniel Veillardd4501d72005-07-24 14:27:16 +00003213#ifdef LIBXML_SCHEMATRON_ENABLED
3214 } else if ((!strcmp(argv[i], "-schematron")) ||
3215 (!strcmp(argv[i], "--schematron"))) {
3216 i++;
3217 schematron = argv[i];
3218 noent++;
3219#endif
Daniel Veillarde8b09e42003-05-13 22:14:13 +00003220 } else if ((!strcmp(argv[i], "-nonet")) ||
3221 (!strcmp(argv[i], "--nonet"))) {
Daniel Veillard61b93382003-11-03 14:28:31 +00003222 options |= XML_PARSE_NONET;
Daniel Veillard968d6432006-04-25 16:17:53 +00003223 xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
Daniel Veillard8874b942005-08-25 13:19:21 +00003224 } else if ((!strcmp(argv[i], "-nocompact")) ||
3225 (!strcmp(argv[i], "--nocompact"))) {
3226 options &= ~XML_PARSE_COMPACT;
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003227 } else if ((!strcmp(argv[i], "-load-trace")) ||
3228 (!strcmp(argv[i], "--load-trace"))) {
3229 load_trace++;
3230 } else if ((!strcmp(argv[i], "-path")) ||
3231 (!strcmp(argv[i], "--path"))) {
3232 i++;
3233 parsePath(BAD_CAST argv[i]);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003234#ifdef LIBXML_PATTERN_ENABLED
3235 } else if ((!strcmp(argv[i], "-pattern")) ||
3236 (!strcmp(argv[i], "--pattern"))) {
3237 i++;
3238 pattern = argv[i];
3239#endif
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003240 } else {
3241 fprintf(stderr, "Unknown option %s\n", argv[i]);
3242 usage(argv[0]);
3243 return(1);
3244 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003245 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003246
3247#ifdef LIBXML_CATALOG_ENABLED
3248 if (nocatalogs == 0) {
3249 if (catalogs) {
3250 const char *catal;
3251
3252 catal = getenv("SGML_CATALOG_FILES");
Daniel Veillard6c5f9d12001-08-25 13:33:14 +00003253 if (catal != NULL) {
3254 xmlLoadCatalogs(catal);
3255 } else {
3256 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
3257 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00003258 }
3259 }
3260#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003261
Daniel Veillard81273902003-09-30 00:43:48 +00003262#ifdef LIBXML_SAX1_ENABLED
Daniel Veillard07cb8222003-09-10 10:51:05 +00003263 if (sax1)
3264 xmlSAXDefaultVersion(1);
3265 else
3266 xmlSAXDefaultVersion(2);
Daniel Veillard81273902003-09-30 00:43:48 +00003267#endif /* LIBXML_SAX1_ENABLED */
Daniel Veillard07cb8222003-09-10 10:51:05 +00003268
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003269 if (chkregister) {
3270 xmlRegisterNodeDefault(registerNode);
3271 xmlDeregisterNodeDefault(deregisterNode);
3272 }
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00003273
3274 indent = getenv("XMLLINT_INDENT");
3275 if(indent != NULL) {
3276 xmlTreeIndentString = indent;
3277 }
3278
Daniel Veillard8a1b1852003-01-05 22:37:17 +00003279
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003280 defaultEntityLoader = xmlGetExternalEntityLoader();
3281 xmlSetExternalEntityLoader(xmllintExternalEntityLoader);
3282
Daniel Veillardd9bad132001-07-23 19:39:43 +00003283 xmlLineNumbersDefault(1);
Daniel Veillard48da9102001-08-07 01:10:10 +00003284 if (loaddtd != 0)
3285 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
3286 if (dtdattrs)
3287 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003288 if (noent != 0) xmlSubstituteEntitiesDefault(1);
Daniel Veillard4432df22003-09-28 18:58:27 +00003289#ifdef LIBXML_VALID_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003290 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
Daniel Veillard4432df22003-09-28 18:58:27 +00003291#endif /* LIBXML_VALID_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003292 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003293 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003294 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003295 xmlGenericError(xmlGenericErrorContext,
3296 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
3297 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003298 "<html><head><title>%s output</title></head>\n",
3299 argv[0]);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003300 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003301 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
3302 argv[0]);
3303 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003304
Daniel Veillardd4501d72005-07-24 14:27:16 +00003305#ifdef LIBXML_SCHEMATRON_ENABLED
3306 if ((schematron != NULL) && (sax == 0)
3307#ifdef LIBXML_READER_ENABLED
3308 && (stream == 0)
3309#endif /* LIBXML_READER_ENABLED */
3310 ) {
3311 xmlSchematronParserCtxtPtr ctxt;
3312
3313 /* forces loading the DTDs */
3314 xmlLoadExtDtdDefaultValue |= 1;
3315 options |= XML_PARSE_DTDLOAD;
3316 if (timing) {
3317 startTimer();
3318 }
3319 ctxt = xmlSchematronNewParserCtxt(schematron);
3320#if 0
3321 xmlSchematronSetParserErrors(ctxt,
3322 (xmlSchematronValidityErrorFunc) fprintf,
3323 (xmlSchematronValidityWarningFunc) fprintf,
3324 stderr);
3325#endif
3326 wxschematron = xmlSchematronParse(ctxt);
3327 if (wxschematron == NULL) {
3328 xmlGenericError(xmlGenericErrorContext,
3329 "Schematron schema %s failed to compile\n", schematron);
3330 progresult = XMLLINT_ERR_SCHEMACOMP;
3331 schematron = NULL;
3332 }
3333 xmlSchematronFreeParserCtxt(ctxt);
3334 if (timing) {
3335 endTimer("Compiling the schemas");
3336 }
3337 }
3338#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00003339#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003340 if ((relaxng != NULL) && (sax == 0)
Daniel Veillard81273902003-09-30 00:43:48 +00003341#ifdef LIBXML_READER_ENABLED
3342 && (stream == 0)
3343#endif /* LIBXML_READER_ENABLED */
3344 ) {
Daniel Veillard71531f32003-02-05 13:19:53 +00003345 xmlRelaxNGParserCtxtPtr ctxt;
3346
Daniel Veillardce192eb2003-04-16 15:58:05 +00003347 /* forces loading the DTDs */
3348 xmlLoadExtDtdDefaultValue |= 1;
Daniel Veillard16fa96c2003-09-23 21:50:54 +00003349 options |= XML_PARSE_DTDLOAD;
Daniel Veillard42f12e92003-03-07 18:32:59 +00003350 if (timing) {
3351 startTimer();
3352 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003353 ctxt = xmlRelaxNGNewParserCtxt(relaxng);
3354 xmlRelaxNGSetParserErrors(ctxt,
3355 (xmlRelaxNGValidityErrorFunc) fprintf,
3356 (xmlRelaxNGValidityWarningFunc) fprintf,
3357 stderr);
3358 relaxngschemas = xmlRelaxNGParse(ctxt);
Daniel Veillardce192eb2003-04-16 15:58:05 +00003359 if (relaxngschemas == NULL) {
3360 xmlGenericError(xmlGenericErrorContext,
3361 "Relax-NG schema %s failed to compile\n", relaxng);
William M. Brack8304d872004-06-08 13:29:32 +00003362 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillardce192eb2003-04-16 15:58:05 +00003363 relaxng = NULL;
3364 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003365 xmlRelaxNGFreeParserCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00003366 if (timing) {
3367 endTimer("Compiling the schemas");
3368 }
Daniel Veillardebe25d42004-03-25 09:35:49 +00003369 } else if ((schema != NULL)
3370#ifdef LIBXML_READER_ENABLED
Daniel Veillardf10ae122005-07-10 19:03:16 +00003371 && (stream == 0)
Daniel Veillardebe25d42004-03-25 09:35:49 +00003372#endif
3373 ) {
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003374 xmlSchemaParserCtxtPtr ctxt;
3375
3376 if (timing) {
3377 startTimer();
3378 }
3379 ctxt = xmlSchemaNewParserCtxt(schema);
3380 xmlSchemaSetParserErrors(ctxt,
3381 (xmlSchemaValidityErrorFunc) fprintf,
3382 (xmlSchemaValidityWarningFunc) fprintf,
3383 stderr);
3384 wxschemas = xmlSchemaParse(ctxt);
3385 if (wxschemas == NULL) {
3386 xmlGenericError(xmlGenericErrorContext,
3387 "WXS schema %s failed to compile\n", schema);
William M. Brack8304d872004-06-08 13:29:32 +00003388 progresult = XMLLINT_ERR_SCHEMACOMP;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003389 schema = NULL;
3390 }
3391 xmlSchemaFreeParserCtxt(ctxt);
3392 if (timing) {
3393 endTimer("Compiling the schemas");
3394 }
Daniel Veillard71531f32003-02-05 13:19:53 +00003395 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003396#endif /* LIBXML_SCHEMAS_ENABLED */
3397#ifdef LIBXML_PATTERN_ENABLED
Daniel Veillard39e5c892005-07-03 22:48:50 +00003398 if ((pattern != NULL)
Daniel Veillardc9352532005-07-04 14:25:34 +00003399#ifdef LIBXML_READER_ENABLED
Daniel Veillard39e5c892005-07-03 22:48:50 +00003400 && (walker == 0)
3401#endif
3402 ) {
Daniel Veillardffa7b7e2003-12-05 16:10:21 +00003403 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003404 if (patternc == NULL) {
3405 xmlGenericError(xmlGenericErrorContext,
3406 "Pattern %s failed to compile\n", pattern);
William M. Brack8304d872004-06-08 13:29:32 +00003407 progresult = XMLLINT_ERR_SCHEMAPAT;
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003408 pattern = NULL;
3409 }
3410 }
3411#endif /* LIBXML_PATTERN_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003412 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +00003413 if ((!strcmp(argv[i], "-encode")) ||
3414 (!strcmp(argv[i], "--encode"))) {
3415 i++;
3416 continue;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00003417 } else if ((!strcmp(argv[i], "-o")) ||
3418 (!strcmp(argv[i], "-output")) ||
3419 (!strcmp(argv[i], "--output"))) {
3420 i++;
3421 continue;
Daniel Veillardbe803962000-06-28 23:40:59 +00003422 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003423#ifdef LIBXML_VALID_ENABLED
Daniel Veillardcd429612000-10-11 15:57:05 +00003424 if ((!strcmp(argv[i], "-dtdvalid")) ||
3425 (!strcmp(argv[i], "--dtdvalid"))) {
3426 i++;
3427 continue;
Daniel Veillard0bff36d2004-08-31 09:37:03 +00003428 }
3429 if ((!strcmp(argv[i], "-path")) ||
3430 (!strcmp(argv[i], "--path"))) {
3431 i++;
3432 continue;
Daniel Veillardcd429612000-10-11 15:57:05 +00003433 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00003434 if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3435 (!strcmp(argv[i], "--dtdvalidfpi"))) {
3436 i++;
3437 continue;
3438 }
Daniel Veillard4432df22003-09-28 18:58:27 +00003439#endif /* LIBXML_VALID_ENABLED */
Daniel Veillard71531f32003-02-05 13:19:53 +00003440 if ((!strcmp(argv[i], "-relaxng")) ||
3441 (!strcmp(argv[i], "--relaxng"))) {
3442 i++;
3443 continue;
3444 }
Daniel Veillard87076042004-05-03 22:54:49 +00003445 if ((!strcmp(argv[i], "-maxmem")) ||
3446 (!strcmp(argv[i], "--maxmem"))) {
3447 i++;
3448 continue;
3449 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003450 if ((!strcmp(argv[i], "-schema")) ||
3451 (!strcmp(argv[i], "--schema"))) {
3452 i++;
3453 continue;
3454 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00003455 if ((!strcmp(argv[i], "-schematron")) ||
3456 (!strcmp(argv[i], "--schematron"))) {
3457 i++;
3458 continue;
3459 }
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003460#ifdef LIBXML_PATTERN_ENABLED
3461 if ((!strcmp(argv[i], "-pattern")) ||
3462 (!strcmp(argv[i], "--pattern"))) {
3463 i++;
3464 continue;
3465 }
3466#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00003467 if ((timing) && (repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00003468 startTimer();
Daniel Veillardcbaf3992001-12-31 16:16:02 +00003469 /* Remember file names. "-" means stdin. <sven@zen.org> */
Daniel Veillard4a6845d2001-01-03 13:32:39 +00003470 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003471 if (repeat) {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003472 xmlParserCtxtPtr ctxt = NULL;
3473
3474 for (acount = 0;acount < repeat;acount++) {
Daniel Veillard81273902003-09-30 00:43:48 +00003475#ifdef LIBXML_READER_ENABLED
Daniel Veillard198c1bf2003-10-20 17:07:41 +00003476 if (stream != 0) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00003477 streamFile(argv[i]);
Daniel Veillard198c1bf2003-10-20 17:07:41 +00003478 } else {
Daniel Veillard81273902003-09-30 00:43:48 +00003479#endif /* LIBXML_READER_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003480 if (sax) {
3481 testSAX(argv[i]);
3482 } else {
3483 if (ctxt == NULL)
3484 ctxt = xmlNewParserCtxt();
3485 parseAndPrintFile(argv[i], ctxt);
3486 }
Daniel Veillard81273902003-09-30 00:43:48 +00003487#ifdef LIBXML_READER_ENABLED
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003488 }
Daniel Veillard81273902003-09-30 00:43:48 +00003489#endif /* LIBXML_READER_ENABLED */
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003490 }
3491 if (ctxt != NULL)
3492 xmlFreeParserCtxt(ctxt);
Daniel Veillard7704fb12003-01-03 16:19:51 +00003493 } else {
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003494 nbregister = 0;
3495
Daniel Veillard81273902003-09-30 00:43:48 +00003496#ifdef LIBXML_READER_ENABLED
Daniel Veillard7704fb12003-01-03 16:19:51 +00003497 if (stream != 0)
3498 streamFile(argv[i]);
3499 else
Daniel Veillard81273902003-09-30 00:43:48 +00003500#endif /* LIBXML_READER_ENABLED */
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003501 if (sax) {
3502 testSAX(argv[i]);
3503 } else {
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003504 parseAndPrintFile(argv[i], NULL);
Daniel Veillardf0af8ec2005-07-08 17:27:33 +00003505 }
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003506
3507 if ((chkregister) && (nbregister != 0)) {
3508 fprintf(stderr, "Registration count off: %d\n", nbregister);
William M. Brack8304d872004-06-08 13:29:32 +00003509 progresult = XMLLINT_ERR_RDREGIS;
Daniel Veillarda2d51fc2004-04-30 22:25:59 +00003510 }
Daniel Veillard7704fb12003-01-03 16:19:51 +00003511 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003512 files ++;
Daniel Veillarda7866932001-12-04 13:14:44 +00003513 if ((timing) && (repeat)) {
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00003514 endTimer("%d iterations", repeat);
Daniel Veillarda7866932001-12-04 13:14:44 +00003515 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00003516 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003517 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00003518 if (generate)
Daniel Veillarde96a2a42003-09-24 21:23:56 +00003519 parseAndPrintFile(NULL, NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003520 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00003521 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003522 }
Daniel Veillard845cce42002-01-09 11:51:37 +00003523 if ((files == 0) && (!generate) && (version == 0)) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00003524 usage(argv[0]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003525 }
Daniel Veillardd4501d72005-07-24 14:27:16 +00003526#ifdef LIBXML_SCHEMATRON_ENABLED
3527 if (wxschematron != NULL)
3528 xmlSchematronFree(wxschematron);
3529#endif
Daniel Veillard71531f32003-02-05 13:19:53 +00003530#ifdef LIBXML_SCHEMAS_ENABLED
3531 if (relaxngschemas != NULL)
3532 xmlRelaxNGFree(relaxngschemas);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00003533 if (wxschemas != NULL)
3534 xmlSchemaFree(wxschemas);
Daniel Veillard71531f32003-02-05 13:19:53 +00003535 xmlRelaxNGCleanupTypes();
3536#endif
Daniel Veillardb3de70c2003-12-02 22:32:15 +00003537#ifdef LIBXML_PATTERN_ENABLED
3538 if (patternc != NULL)
3539 xmlFreePattern(patternc);
3540#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003541 xmlCleanupParser();
3542 xmlMemoryDump();
3543
Daniel Veillardf7cd4812001-02-23 18:44:52 +00003544 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00003545}
Daniel Veillard88a172f2000-08-04 18:23:10 +00003546