blob: 9fffb6b5d84b85ed4d05a2c5f182100080b611bc [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 Veillard28ae6362001-07-14 16:44:32 +000013
Daniel Veillard8a1b1852003-01-05 22:37:17 +000014#include <assert.h>
15
Daniel Veillard3c5ed912002-01-08 10:36:16 +000016#if defined (_WIN32) && !defined(__CYGWIN__)
Daniel Veillard2d90de42001-04-16 17:46:18 +000017#ifdef _MSC_VER
18#include <winsock2.h>
19#pragma comment(lib, "ws2_32.lib")
20#define gettimeofday(p1,p2)
Daniel Veillardf216d462002-02-08 13:44:24 +000021#include <time.h>
Daniel Veillard28ae6362001-07-14 16:44:32 +000022#else /* _MSC_VER */
23#include <sys/time.h>
Daniel Veillard2d90de42001-04-16 17:46:18 +000024#endif /* _MSC_VER */
25#else /* _WIN32 */
Daniel Veillarded472f32001-12-13 08:48:14 +000026#ifdef HAVE_SYS_TIME_H
Daniel Veillard48b2f892001-02-25 16:11:03 +000027#include <sys/time.h>
Daniel Veillarded472f32001-12-13 08:48:14 +000028#endif
Daniel Veillard01db67c2001-12-18 07:09:59 +000029#ifdef HAVE_TIME_H
30#include <time.h>
31#endif
Daniel Veillard2d90de42001-04-16 17:46:18 +000032#endif /* _WIN32 */
Daniel Veillard48b2f892001-02-25 16:11:03 +000033
Daniel Veillard1638a472003-08-14 01:23:25 +000034#ifdef __MINGW32__
35#define _WINSOCKAPI_
36#include <wsockcompat.h>
37#include <winsock2.h>
38#undef SOCKLEN_T
39#define SOCKLEN_T unsigned int
40#endif
41
42
Daniel Veillard90bc3712002-03-07 15:12:58 +000043#ifdef HAVE_SYS_TIMEB_H
44#include <sys/timeb.h>
45#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000046
47#ifdef HAVE_SYS_TYPES_H
48#include <sys/types.h>
49#endif
50#ifdef HAVE_SYS_STAT_H
51#include <sys/stat.h>
52#endif
53#ifdef HAVE_FCNTL_H
54#include <fcntl.h>
55#endif
56#ifdef HAVE_UNISTD_H
57#include <unistd.h>
58#endif
Daniel Veillard46e370e2000-07-21 20:32:03 +000059#ifdef HAVE_SYS_MMAN_H
60#include <sys/mman.h>
Daniel Veillard87b95392000-08-12 21:12:04 +000061/* seems needed for Solaris */
62#ifndef MAP_FAILED
63#define MAP_FAILED ((void *) -1)
64#endif
Daniel Veillard46e370e2000-07-21 20:32:03 +000065#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000066#ifdef HAVE_STDLIB_H
67#include <stdlib.h>
68#endif
69#ifdef HAVE_LIBREADLINE
70#include <readline/readline.h>
71#ifdef HAVE_LIBHISTORY
72#include <readline/history.h>
73#endif
74#endif
75
76#include <libxml/xmlmemory.h>
77#include <libxml/parser.h>
78#include <libxml/parserInternals.h>
79#include <libxml/HTMLparser.h>
80#include <libxml/HTMLtree.h>
81#include <libxml/tree.h>
82#include <libxml/xpath.h>
83#include <libxml/debugXML.h>
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +000084#include <libxml/xmlerror.h>
Daniel Veillard9e8bfae2000-11-06 16:43:11 +000085#ifdef LIBXML_XINCLUDE_ENABLED
86#include <libxml/xinclude.h>
87#endif
Daniel Veillard81418e32001-05-22 15:08:55 +000088#ifdef LIBXML_CATALOG_ENABLED
89#include <libxml/catalog.h>
90#endif
Daniel Veillard89cad532001-10-22 09:46:13 +000091#ifdef LIBXML_DOCB_ENABLED
92#include <libxml/DOCBparser.h>
93#endif
Daniel Veillard3c01b1d2001-10-17 15:58:35 +000094#include <libxml/globals.h>
Daniel Veillard7704fb12003-01-03 16:19:51 +000095#include <libxml/xmlreader.h>
Daniel Veillard71531f32003-02-05 13:19:53 +000096#ifdef LIBXML_SCHEMAS_ENABLED
97#include <libxml/relaxng.h>
Daniel Veillard75bb3bb2003-05-12 15:25:56 +000098#include <libxml/xmlschemas.h>
Daniel Veillard71531f32003-02-05 13:19:53 +000099#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000100
Daniel Veillard3be27512003-01-26 19:49:04 +0000101#ifndef XML_XML_DEFAULT_CATALOG
102#define XML_XML_DEFAULT_CATALOG "file:///etc/xml/catalog"
103#endif
104
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000105#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000106static int shell = 0;
107static int debugent = 0;
108#endif
Daniel Veillard8326e732003-01-07 00:19:07 +0000109static int debug = 0;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000110static int copy = 0;
111static int recovery = 0;
112static int noent = 0;
113static int noout = 0;
114static int nowrap = 0;
115static int valid = 0;
116static int postvalid = 0;
Daniel Veillardcd429612000-10-11 15:57:05 +0000117static char * dtdvalid = NULL;
Daniel Veillard66f68e72003-08-18 16:39:51 +0000118static char * dtdvalidfpi = NULL;
Daniel Veillard71531f32003-02-05 13:19:53 +0000119#ifdef LIBXML_SCHEMAS_ENABLED
120static char * relaxng = NULL;
121static xmlRelaxNGPtr relaxngschemas = NULL;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +0000122static char * schema = NULL;
123static xmlSchemaPtr wxschemas = NULL;
Daniel Veillard71531f32003-02-05 13:19:53 +0000124#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000125static int repeat = 0;
126static int insert = 0;
127static int compress = 0;
Daniel Veillard89cad532001-10-22 09:46:13 +0000128#ifdef LIBXML_DOCB_ENABLED
129static int sgml = 0;
130#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000131static int html = 0;
132static int htmlout = 0;
133static int push = 0;
Daniel Veillard46e370e2000-07-21 20:32:03 +0000134#ifdef HAVE_SYS_MMAN_H
135static int memory = 0;
136#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000137static int noblanks = 0;
Daniel Veillard90493a92001-08-14 14:12:47 +0000138static int format = 0;
Daniel Veillard5e873c42000-04-12 13:27:38 +0000139static int testIO = 0;
Daniel Veillardbe803962000-06-28 23:40:59 +0000140static char *encoding = NULL;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000141#ifdef LIBXML_XINCLUDE_ENABLED
142static int xinclude = 0;
143#endif
Daniel Veillard48da9102001-08-07 01:10:10 +0000144static int dtdattrs = 0;
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000145static int loaddtd = 0;
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000146static int progresult = 0;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000147static int timing = 0;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000148static int generate = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000149static int dropdtd = 0;
Daniel Veillarde2940dd2001-08-22 00:06:49 +0000150#ifdef LIBXML_CATALOG_ENABLED
151static int catalogs = 0;
152static int nocatalogs = 0;
153#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +0000154static int stream = 0;
Daniel Veillard8a1b1852003-01-05 22:37:17 +0000155static int chkregister = 0;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +0000156static const char *output = NULL;
157
Daniel Veillard01db67c2001-12-18 07:09:59 +0000158/*
159 * Internal timing routines to remove the necessity to have unix-specific
160 * function calls
161 */
162
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000163#ifndef HAVE_GETTIMEOFDAY
164#ifdef HAVE_SYS_TIMEB_H
165#ifdef HAVE_SYS_TIME_H
166#ifdef HAVE_FTIME
167
Daniel Veillard01c13b52002-12-10 15:19:08 +0000168static int
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000169my_gettimeofday(struct timeval *tvp, void *tzp)
170{
171 struct timeb timebuffer;
172
173 ftime(&timebuffer);
174 if (tvp) {
175 tvp->tv_sec = timebuffer.time;
176 tvp->tv_usec = timebuffer.millitm * 1000L;
177 }
178 return (0);
179}
180#define HAVE_GETTIMEOFDAY 1
181#define gettimeofday my_gettimeofday
182
183#endif /* HAVE_FTIME */
184#endif /* HAVE_SYS_TIME_H */
185#endif /* HAVE_SYS_TIMEB_H */
186#endif /* !HAVE_GETTIMEOFDAY */
187
Daniel Veillard01db67c2001-12-18 07:09:59 +0000188#if defined(HAVE_GETTIMEOFDAY)
189static struct timeval begin, end;
190
191/*
192 * startTimer: call where you want to start timing
193 */
194static void
195startTimer(void)
196{
197 gettimeofday(&begin, NULL);
198}
199
200/*
201 * endTimer: call where you want to stop timing and to print out a
202 * message about the timing performed; format is a printf
203 * type argument
204 */
205static void
Daniel Veillard118aed72002-09-24 14:13:13 +0000206endTimer(const char *fmt, ...)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000207{
208 long msec;
209 va_list ap;
210
211 gettimeofday(&end, NULL);
212 msec = end.tv_sec - begin.tv_sec;
213 msec *= 1000;
214 msec += (end.tv_usec - begin.tv_usec) / 1000;
215
216#ifndef HAVE_STDARG_H
217#error "endTimer required stdarg functions"
218#endif
Daniel Veillard118aed72002-09-24 14:13:13 +0000219 va_start(ap, fmt);
220 vfprintf(stderr, fmt, ap);
Daniel Veillard01db67c2001-12-18 07:09:59 +0000221 va_end(ap);
222
223 fprintf(stderr, " took %ld ms\n", msec);
224}
225#elif defined(HAVE_TIME_H)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000226/*
227 * No gettimeofday function, so we have to make do with calling clock.
228 * This is obviously less accurate, but there's little we can do about
229 * that.
230 */
Daniel Veillard90bc3712002-03-07 15:12:58 +0000231#ifndef CLOCKS_PER_SEC
232#define CLOCKS_PER_SEC 100
233#endif
Daniel Veillard01db67c2001-12-18 07:09:59 +0000234
235static clock_t begin, end;
236static void
237startTimer(void)
238{
239 begin = clock();
240}
241static void
242endTimer(const char *fmt, ...)
243{
244 long msec;
245 va_list ap;
246
247 end = clock();
248 msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
249
250#ifndef HAVE_STDARG_H
251#error "endTimer required stdarg functions"
252#endif
253 va_start(ap, fmt);
254 vfprintf(stderr, fmt, ap);
255 va_end(ap);
256 fprintf(stderr, " took %ld ms\n", msec);
257}
258#else
259
260/*
261 * We don't have a gettimeofday or time.h, so we just don't do timing
262 */
263static void
264startTimer(void)
265{
266 /*
267 * Do nothing
268 */
269}
270static void
271endTimer(char *format, ...)
272{
273 /*
274 * We cannot do anything because we don't have a timing function
275 */
276#ifdef HAVE_STDARG_H
277 va_start(ap, format);
278 vfprintf(stderr, format, ap);
279 va_end(ap);
280 fprintf(stderr, " was not timed\n", msec);
281#else
282 /* We don't have gettimeofday, time or stdarg.h, what crazy world is
283 * this ?!
284 */
285#endif
286}
287#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000288/************************************************************************
289 * *
290 * HTML ouput *
291 * *
292 ************************************************************************/
293char buffer[50000];
294
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000295static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000296xmlHTMLEncodeSend(void) {
297 char *result;
298
299 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
300 if (result) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000301 xmlGenericError(xmlGenericErrorContext, "%s", result);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000302 xmlFree(result);
303 }
304 buffer[0] = 0;
305}
306
307/**
308 * xmlHTMLPrintFileInfo:
309 * @input: an xmlParserInputPtr input
310 *
311 * Displays the associated file and line informations for the current input
312 */
313
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000314static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000315xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000316 int len;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000317 xmlGenericError(xmlGenericErrorContext, "<p>");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000318
319 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000320 if (input != NULL) {
321 if (input->filename) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000322 snprintf(&buffer[len], sizeof(buffer) - len, "%s:%d: ", input->filename,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000323 input->line);
324 } else {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000325 snprintf(&buffer[len], sizeof(buffer) - len, "Entity: line %d: ", input->line);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000326 }
327 }
328 xmlHTMLEncodeSend();
329}
330
331/**
332 * xmlHTMLPrintFileContext:
333 * @input: an xmlParserInputPtr input
334 *
335 * Displays current context within the input content for error tracking
336 */
337
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000338static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000339xmlHTMLPrintFileContext(xmlParserInputPtr input) {
340 const xmlChar *cur, *base;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000341 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000342 int n;
343
344 if (input == NULL) return;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000345 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000346 cur = input->cur;
347 base = input->base;
348 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
349 cur--;
350 }
351 n = 0;
352 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
353 cur--;
354 if ((*cur == '\n') || (*cur == '\r')) cur++;
355 base = cur;
356 n = 0;
357 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000358 len = strlen(buffer);
359 snprintf(&buffer[len], sizeof(buffer) - len, "%c",
360 (unsigned char) *cur++);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000361 n++;
362 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000363 len = strlen(buffer);
364 snprintf(&buffer[len], sizeof(buffer) - len, "\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000365 cur = input->cur;
366 while ((*cur == '\n') || (*cur == '\r'))
367 cur--;
368 n = 0;
369 while ((cur != base) && (n++ < 80)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000370 len = strlen(buffer);
371 snprintf(&buffer[len], sizeof(buffer) - len, " ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000372 base++;
373 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000374 len = strlen(buffer);
375 snprintf(&buffer[len], sizeof(buffer) - len, "^\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000376 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000377 xmlGenericError(xmlGenericErrorContext, "</pre>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000378}
379
380/**
381 * xmlHTMLError:
382 * @ctx: an XML parser context
383 * @msg: the message to display/transmit
384 * @...: extra parameters for the message display
385 *
386 * Display and format an error messages, gives file, line, position and
387 * extra parameters.
388 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000389static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000390xmlHTMLError(void *ctx, const char *msg, ...)
391{
392 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
393 xmlParserInputPtr input;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000394 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000395 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000396
397 buffer[0] = 0;
398 input = ctxt->input;
399 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000400 input = ctxt->inputTab[ctxt->inputNr - 2];
401 }
402
403 xmlHTMLPrintFileInfo(input);
404
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000405 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000406 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000407 len = strlen(buffer);
408 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000409 va_end(args);
410 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000411 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000412
413 xmlHTMLPrintFileContext(input);
414 xmlHTMLEncodeSend();
415}
416
417/**
418 * xmlHTMLWarning:
419 * @ctx: an XML parser context
420 * @msg: the message to display/transmit
421 * @...: extra parameters for the message display
422 *
423 * Display and format a warning messages, gives file, line, position and
424 * extra parameters.
425 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000426static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000427xmlHTMLWarning(void *ctx, const char *msg, ...)
428{
429 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
430 xmlParserInputPtr input;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000431 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000432 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000433
434 buffer[0] = 0;
435 input = ctxt->input;
436 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000437 input = ctxt->inputTab[ctxt->inputNr - 2];
438 }
439
440
441 xmlHTMLPrintFileInfo(input);
442
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000443 xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000444 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000445 len = strlen(buffer);
446 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000447 va_end(args);
448 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000449 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000450
451 xmlHTMLPrintFileContext(input);
452 xmlHTMLEncodeSend();
453}
454
455/**
456 * xmlHTMLValidityError:
457 * @ctx: an XML parser context
458 * @msg: the message to display/transmit
459 * @...: extra parameters for the message display
460 *
461 * Display and format an validity error messages, gives file,
462 * line, position and extra parameters.
463 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000464static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000465xmlHTMLValidityError(void *ctx, const char *msg, ...)
466{
467 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
468 xmlParserInputPtr input;
469 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000470 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000471
472 buffer[0] = 0;
473 input = ctxt->input;
474 if ((input->filename == NULL) && (ctxt->inputNr > 1))
475 input = ctxt->inputTab[ctxt->inputNr - 2];
476
477 xmlHTMLPrintFileInfo(input);
478
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000479 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000480 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000481 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000482 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000483 va_end(args);
484 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000485 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000486
487 xmlHTMLPrintFileContext(input);
488 xmlHTMLEncodeSend();
489}
490
491/**
492 * xmlHTMLValidityWarning:
493 * @ctx: an XML parser context
494 * @msg: the message to display/transmit
495 * @...: extra parameters for the message display
496 *
497 * Display and format a validity warning messages, gives file, line,
498 * position and extra parameters.
499 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000500static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000501xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
502{
503 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
504 xmlParserInputPtr input;
505 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000506 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000507
508 buffer[0] = 0;
509 input = ctxt->input;
510 if ((input->filename == NULL) && (ctxt->inputNr > 1))
511 input = ctxt->inputTab[ctxt->inputNr - 2];
512
513 xmlHTMLPrintFileInfo(input);
514
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000515 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000516 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000517 len = strlen(buffer);
518 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000519 va_end(args);
520 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000521 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000522
523 xmlHTMLPrintFileContext(input);
524 xmlHTMLEncodeSend();
525}
526
527/************************************************************************
528 * *
529 * Shell Interface *
530 * *
531 ************************************************************************/
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000532#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000533/**
534 * xmlShellReadline:
535 * @prompt: the prompt value
536 *
537 * Read a string
538 *
539 * Returns a pointer to it or NULL on EOF the caller is expected to
540 * free the returned string.
541 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000542static char *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000543xmlShellReadline(char *prompt) {
544#ifdef HAVE_LIBREADLINE
545 char *line_read;
546
547 /* Get a line from the user. */
548 line_read = readline (prompt);
549
550 /* If the line has any text in it, save it on the history. */
551 if (line_read && *line_read)
552 add_history (line_read);
553
554 return (line_read);
555#else
556 char line_read[501];
Daniel Veillard29e43992001-12-13 22:21:58 +0000557 char *ret;
558 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000559
560 if (prompt != NULL)
561 fprintf(stdout, "%s", prompt);
562 if (!fgets(line_read, 500, stdin))
563 return(NULL);
564 line_read[500] = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000565 len = strlen(line_read);
566 ret = (char *) malloc(len + 1);
567 if (ret != NULL) {
568 memcpy (ret, line_read, len + 1);
569 }
570 return(ret);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000571#endif
572}
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000573#endif /* LIBXML_DEBUG_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000574
575/************************************************************************
576 * *
Daniel Veillard5e873c42000-04-12 13:27:38 +0000577 * I/O Interfaces *
578 * *
579 ************************************************************************/
580
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000581static int myRead(FILE *f, char * buf, int len) {
582 return(fread(buf, 1, len, f));
Daniel Veillard5e873c42000-04-12 13:27:38 +0000583}
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000584static void myClose(FILE *f) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000585 if (f != stdin) {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000586 fclose(f);
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000587 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000588}
589
590/************************************************************************
591 * *
Daniel Veillard7704fb12003-01-03 16:19:51 +0000592 * Stream Test processing *
593 * *
594 ************************************************************************/
Daniel Veillard7704fb12003-01-03 16:19:51 +0000595static void processNode(xmlTextReaderPtr reader) {
Daniel Veillarde59494f2003-01-04 16:35:29 +0000596 xmlChar *name, *value;
Daniel Veillard7704fb12003-01-03 16:19:51 +0000597
Daniel Veillarde59494f2003-01-04 16:35:29 +0000598 name = xmlTextReaderName(reader);
599 if (name == NULL)
600 name = xmlStrdup(BAD_CAST "--");
Daniel Veillard99737f52003-03-22 14:55:50 +0000601
Daniel Veillarde59494f2003-01-04 16:35:29 +0000602 value = xmlTextReaderValue(reader);
Daniel Veillard7704fb12003-01-03 16:19:51 +0000603
Daniel Veillard99737f52003-03-22 14:55:50 +0000604 printf("%d %d %s %d %d",
Daniel Veillarde59494f2003-01-04 16:35:29 +0000605 xmlTextReaderDepth(reader),
606 xmlTextReaderNodeType(reader),
607 name,
Daniel Veillard99737f52003-03-22 14:55:50 +0000608 xmlTextReaderIsEmptyElement(reader),
609 xmlTextReaderHasValue(reader));
Daniel Veillarde59494f2003-01-04 16:35:29 +0000610 xmlFree(name);
611 if (value == NULL)
612 printf("\n");
613 else {
614 printf(" %s\n", value);
615 xmlFree(value);
Daniel Veillard7704fb12003-01-03 16:19:51 +0000616 }
617}
618
619static void streamFile(char *filename) {
620 xmlTextReaderPtr reader;
621 int ret;
622
Daniel Veillard7704fb12003-01-03 16:19:51 +0000623 reader = xmlNewTextReaderFilename(filename);
624 if (reader != NULL) {
625 if (valid)
626 xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
Daniel Veillardce192eb2003-04-16 15:58:05 +0000627 else
628 xmlTextReaderSetParserProp(reader, XML_PARSER_LOADDTD, 1);
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000629#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +0000630 if (relaxng != NULL) {
631 if (timing) {
632 startTimer();
633 }
634 ret = xmlTextReaderRelaxNGValidate(reader, relaxng);
635 if (ret < 0) {
636 xmlGenericError(xmlGenericErrorContext,
637 "Relax-NG schema %s failed to compile\n", relaxng);
638 relaxng = NULL;
639 }
640 if (timing) {
641 endTimer("Compiling the schemas");
642 }
643 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000644#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +0000645
646 /*
647 * Process all nodes in sequence
648 */
Daniel Veillardce192eb2003-04-16 15:58:05 +0000649 if (timing) {
650 startTimer();
651 }
Daniel Veillard7704fb12003-01-03 16:19:51 +0000652 ret = xmlTextReaderRead(reader);
653 while (ret == 1) {
654 if (debug)
655 processNode(reader);
656 ret = xmlTextReaderRead(reader);
657 }
Daniel Veillardce192eb2003-04-16 15:58:05 +0000658 if (timing) {
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000659#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +0000660 if ((valid) || (relaxng != NULL))
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000661#else
662 if (valid)
663#endif
Daniel Veillardce192eb2003-04-16 15:58:05 +0000664 endTimer("Parsing and validating");
665 else
666 endTimer("Parsing");
667 }
Daniel Veillard7704fb12003-01-03 16:19:51 +0000668
Daniel Veillardf6bad792003-04-11 19:38:54 +0000669 if (valid) {
670 if (xmlTextReaderIsValid(reader) != 1) {
671 xmlGenericError(xmlGenericErrorContext,
672 "Document %s does not validate\n", filename);
673 progresult = 3;
674 }
675 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000676#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf4e55762003-04-15 23:32:22 +0000677 if (relaxng != NULL) {
678 if (xmlTextReaderIsValid(reader) != 1) {
679 printf("%s fails to validate\n", filename);
680 progresult = 3;
681 } else {
682 printf("%s validates\n", filename);
683 }
684 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000685#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +0000686 /*
687 * Done, cleanup and status
688 */
689 xmlFreeTextReader(reader);
690 if (ret != 0) {
691 printf("%s : failed to parse\n", filename);
Daniel Veillardf6bad792003-04-11 19:38:54 +0000692 progresult = 1;
Daniel Veillard7704fb12003-01-03 16:19:51 +0000693 }
694 } else {
695 fprintf(stderr, "Unable to open %s\n", filename);
Daniel Veillardf6bad792003-04-11 19:38:54 +0000696 progresult = 1;
Daniel Veillard7704fb12003-01-03 16:19:51 +0000697 }
698}
699
700/************************************************************************
701 * *
702 * Tree Test processing *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000703 * *
704 ************************************************************************/
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000705static void parseAndPrintFile(char *filename) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000706 xmlDocPtr doc = NULL, tmp;
707
Daniel Veillard48b2f892001-02-25 16:11:03 +0000708 if ((timing) && (!repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +0000709 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +0000710
711
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000712 if (filename == NULL) {
713 if (generate) {
714 xmlNodePtr n;
715
716 doc = xmlNewDoc(BAD_CAST "1.0");
717 n = xmlNewNode(NULL, BAD_CAST "info");
718 xmlNodeSetContent(n, BAD_CAST "abc");
719 xmlDocSetRootElement(doc, n);
720 }
721 }
Daniel Veillard89cad532001-10-22 09:46:13 +0000722#ifdef LIBXML_DOCB_ENABLED
723 /*
724 * build an SGML tree from a string;
725 */
726 else if ((sgml) && (push)) {
727 FILE *f;
728
729 f = fopen(filename, "r");
730 if (f != NULL) {
731 int res, size = 3;
732 char chars[4096];
733 docbParserCtxtPtr ctxt;
734
735 /* if (repeat) */
736 size = 4096;
737 res = fread(chars, 1, 4, f);
738 if (res > 0) {
739 ctxt = docbCreatePushParserCtxt(NULL, NULL,
William M. Brack779af002003-08-01 15:55:39 +0000740 chars, res, filename, XML_CHAR_ENCODING_NONE);
Daniel Veillard89cad532001-10-22 09:46:13 +0000741 while ((res = fread(chars, 1, size, f)) > 0) {
742 docbParseChunk(ctxt, chars, res, 0);
743 }
744 docbParseChunk(ctxt, chars, 0, 1);
745 doc = ctxt->myDoc;
746 docbFreeParserCtxt(ctxt);
747 }
748 fclose(f);
749 }
750 } else if (sgml) {
751 doc = docbParseFile(filename, NULL);
752 }
753#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000754#ifdef LIBXML_HTML_ENABLED
William M. Brack78637da2003-07-31 14:47:38 +0000755 else if ((html) && (push)) {
756 FILE *f;
757
758 f = fopen(filename, "r");
759 if (f != NULL) {
760 int res, size = 3;
761 char chars[4096];
762 htmlParserCtxtPtr ctxt;
763
764 /* if (repeat) */
765 size = 4096;
766 res = fread(chars, 1, 4, f);
767 if (res > 0) {
768 ctxt = htmlCreatePushParserCtxt(NULL, NULL,
769 chars, res, filename, 0);
770 while ((res = fread(chars, 1, size, f)) > 0) {
771 htmlParseChunk(ctxt, chars, res, 0);
772 }
773 htmlParseChunk(ctxt, chars, 0, 1);
774 doc = ctxt->myDoc;
775 htmlFreeParserCtxt(ctxt);
776 }
777 fclose(f);
778 }
779 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000780 else if (html) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000781 doc = htmlParseFile(filename, NULL);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000782 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000783#endif /* LIBXML_HTML_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000784 else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000785 /*
786 * build an XML tree from a string;
787 */
788 if (push) {
789 FILE *f;
790
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000791 /* '-' Usually means stdin -<sven@zen.org> */
792 if ((filename[0] == '-') && (filename[1] == 0)) {
793 f = stdin;
794 } else {
795 f = fopen(filename, "r");
796 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000797 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +0000798 int ret;
Daniel Veillarda880b122003-04-21 21:36:41 +0000799 int res, size = 1024;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000800 char chars[1024];
801 xmlParserCtxtPtr ctxt;
802
Daniel Veillarda880b122003-04-21 21:36:41 +0000803 /* if (repeat) size = 1024; */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000804 res = fread(chars, 1, 4, f);
805 if (res > 0) {
806 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
807 chars, res, filename);
808 while ((res = fread(chars, 1, size, f)) > 0) {
809 xmlParseChunk(ctxt, chars, res, 0);
810 }
811 xmlParseChunk(ctxt, chars, 0, 1);
812 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +0000813 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000814 xmlFreeParserCtxt(ctxt);
Daniel Veillarde715dd22000-08-29 18:29:38 +0000815 if (!ret) {
816 xmlFreeDoc(doc);
817 doc = NULL;
818 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000819 }
820 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000821 } else if (testIO) {
822 int ret;
823 FILE *f;
824
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000825 /* '-' Usually means stdin -<sven@zen.org> */
826 if ((filename[0] == '-') && (filename[1] == 0)) {
827 f = stdin;
828 } else {
829 f = fopen(filename, "r");
830 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000831 if (f != NULL) {
832 xmlParserCtxtPtr ctxt;
833
834 ctxt = xmlCreateIOParserCtxt(NULL, NULL,
835 (xmlInputReadCallback) myRead,
836 (xmlInputCloseCallback) myClose,
837 f, XML_CHAR_ENCODING_NONE);
838 xmlParseDocument(ctxt);
839
840 ret = ctxt->wellFormed;
841 doc = ctxt->myDoc;
842 xmlFreeParserCtxt(ctxt);
843 if (!ret) {
844 xmlFreeDoc(doc);
845 doc = NULL;
846 }
847 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000848 } else if (recovery) {
849 doc = xmlRecoverFile(filename);
850 } else if (htmlout) {
851 int ret;
852 xmlParserCtxtPtr ctxt;
853 xmlSAXHandler silent, *old;
854
855 ctxt = xmlCreateFileParserCtxt(filename);
Daniel Veillard88a172f2000-08-04 18:23:10 +0000856
857 if (ctxt == NULL) {
Daniel Veillardcbaf3992001-12-31 16:16:02 +0000858 /* If xmlCreateFileParserCtxt() return NULL something
Daniel Veillard88a172f2000-08-04 18:23:10 +0000859 strange happened so we don't want to do anything. Do
860 we want to print an error message here?
861 <sven@zen.org> */
Daniel Veillard7ebb1ee2000-08-04 18:24:45 +0000862 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000863 } else {
864 memcpy(&silent, ctxt->sax, sizeof(silent));
865 old = ctxt->sax;
866 silent.error = xmlHTMLError;
867 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000868 silent.warning = xmlHTMLWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000869 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000870 silent.warning = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000871 silent.fatalError = xmlHTMLError;
872 ctxt->sax = &silent;
873 ctxt->vctxt.error = xmlHTMLValidityError;
874 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000875 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000876 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000877 ctxt->vctxt.warning = NULL;
878
Daniel Veillard88a172f2000-08-04 18:23:10 +0000879 xmlParseDocument(ctxt);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000880
Daniel Veillard88a172f2000-08-04 18:23:10 +0000881 ret = ctxt->wellFormed;
882 doc = ctxt->myDoc;
883 ctxt->sax = old;
884 xmlFreeParserCtxt(ctxt);
885 if (!ret) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000886 xmlFreeDoc(doc);
887 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000888 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000889 }
Daniel Veillard46e370e2000-07-21 20:32:03 +0000890#ifdef HAVE_SYS_MMAN_H
891 } else if (memory) {
892 int fd;
893 struct stat info;
894 const char *base;
895 if (stat(filename, &info) < 0)
896 return;
897 if ((fd = open(filename, O_RDONLY)) < 0)
898 return;
899 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillard29579362000-08-14 17:57:48 +0000900 if (base == (void *) MAP_FAILED)
Daniel Veillard46e370e2000-07-21 20:32:03 +0000901 return;
902
903 doc = xmlParseMemory((char *) base, info.st_size);
904 munmap((char *) base, info.st_size);
905#endif
Daniel Veillardea7751d2002-12-20 00:16:24 +0000906 } else if (valid) {
907 int ret;
908 xmlParserCtxtPtr ctxt;
909
910 ctxt = xmlCreateFileParserCtxt(filename);
911
912 if (ctxt == NULL) {
913 doc = NULL;
914 } else {
915 xmlParseDocument(ctxt);
916 if (ctxt->valid == 0)
917 progresult = 4;
918 ret = ctxt->wellFormed;
919 doc = ctxt->myDoc;
920 xmlFreeParserCtxt(ctxt);
921 if (!ret) {
922 xmlFreeDoc(doc);
923 doc = NULL;
924 }
925 }
926 } else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000927 doc = xmlParseFile(filename);
Daniel Veillardea7751d2002-12-20 00:16:24 +0000928 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000929 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000930
Daniel Veillard88a172f2000-08-04 18:23:10 +0000931 /*
932 * If we don't have a document we might as well give up. Do we
933 * want an error message here? <sven@zen.org> */
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000934 if (doc == NULL) {
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000935 progresult = 1;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000936 return;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000937 }
938
Daniel Veillard48b2f892001-02-25 16:11:03 +0000939 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +0000940 endTimer("Parsing");
Daniel Veillard48b2f892001-02-25 16:11:03 +0000941 }
942
Daniel Veillard29e43992001-12-13 22:21:58 +0000943 /*
944 * Remove DOCTYPE nodes
945 */
946 if (dropdtd) {
947 xmlDtdPtr dtd;
948
949 dtd = xmlGetIntSubset(doc);
950 if (dtd != NULL) {
951 xmlUnlinkNode((xmlNodePtr)dtd);
952 xmlFreeDtd(dtd);
953 }
954 }
955
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000956#ifdef LIBXML_XINCLUDE_ENABLED
Daniel Veillard48b2f892001-02-25 16:11:03 +0000957 if (xinclude) {
958 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +0000959 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +0000960 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000961 xmlXIncludeProcess(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000962 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +0000963 endTimer("Xinclude processing");
Daniel Veillard48b2f892001-02-25 16:11:03 +0000964 }
965 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000966#endif
Daniel Veillard88a172f2000-08-04 18:23:10 +0000967
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000968#ifdef LIBXML_DEBUG_ENABLED
969 /*
Daniel Veillardcbaf3992001-12-31 16:16:02 +0000970 * shell interaction
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000971 */
972 if (shell)
973 xmlShell(doc, filename, xmlShellReadline, stdout);
974#endif
975
976 /*
977 * test intermediate copy if needed.
978 */
979 if (copy) {
980 tmp = doc;
981 doc = xmlCopyDoc(doc, 1);
982 xmlFreeDoc(tmp);
983 }
984
985 if ((insert) && (!html)) {
986 const xmlChar* list[256];
987 int nb, i;
988 xmlNodePtr node;
989
990 if (doc->children != NULL) {
991 node = doc->children;
992 while ((node != NULL) && (node->last == NULL)) node = node->next;
993 if (node != NULL) {
994 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
995 if (nb < 0) {
996 printf("could not get valid list of elements\n");
997 } else if (nb == 0) {
MDT 2001 John Fleckbbb9e432001-09-24 03:08:43 +0000998 printf("No element can be inserted under root\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000999 } else {
MDT 2001 John Fleckbbb9e432001-09-24 03:08:43 +00001000 printf("%d element types can be inserted under root:\n",
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001001 nb);
1002 for (i = 0;i < nb;i++) {
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001003 printf("%s\n", (char *) list[i]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001004 }
1005 }
1006 }
1007 }
1008 }else if (noout == 0) {
1009 /*
1010 * print it.
1011 */
1012#ifdef LIBXML_DEBUG_ENABLED
1013 if (!debug) {
1014#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00001015 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001016 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001017 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +00001018#ifdef HAVE_SYS_MMAN_H
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001019 if (memory) {
1020 xmlChar *result;
1021 int len;
1022
1023 if (encoding != NULL) {
Daniel Veillardd536f702001-11-08 17:32:47 +00001024 if ( format ) {
1025 xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
1026 } else {
1027 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
1028 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001029 } else {
Daniel Veillard90493a92001-08-14 14:12:47 +00001030 if (format)
1031 xmlDocDumpFormatMemory(doc, &result, &len, 1);
1032 else
1033 xmlDocDumpMemory(doc, &result, &len);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001034 }
1035 if (result == NULL) {
1036 fprintf(stderr, "Failed to save\n");
1037 } else {
1038 write(1, result, len);
1039 xmlFree(result);
1040 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +00001041 } else
1042#endif /* HAVE_SYS_MMAN_H */
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001043 if (compress) {
1044 xmlSaveFile(output ? output : "-", doc);
1045 }
Daniel Veillardd536f702001-11-08 17:32:47 +00001046 else if (encoding != NULL) {
1047 if ( format ) {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001048 xmlSaveFormatFileEnc(output ? output : "-", doc, encoding, 1);
1049 }
Daniel Veillardd536f702001-11-08 17:32:47 +00001050 else {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001051 xmlSaveFileEnc(output ? output : "-", doc, encoding);
Daniel Veillardd536f702001-11-08 17:32:47 +00001052 }
1053 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001054 else if (format) {
1055 xmlSaveFormatFile(output ? output : "-", doc, 1);
1056 }
1057 else {
1058 FILE *out;
1059 if (output == NULL)
1060 out = stdout;
1061 else {
1062 out = fopen(output,"wb");
1063 }
1064 xmlDocDump(out, doc);
1065
1066 if (output)
1067 fclose(out);
1068 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001069 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001070 endTimer("Saving");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001071 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001072#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001073 } else {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001074 FILE *out;
1075 if (output == NULL)
1076 out = stdout;
1077 else {
1078 out = fopen(output,"wb");
1079 }
1080 xmlDebugDumpDocument(out, doc);
1081
1082 if (output)
1083 fclose(out);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001084 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001085#endif
1086 }
1087
1088 /*
1089 * A posteriori validation test
1090 */
Daniel Veillard66f68e72003-08-18 16:39:51 +00001091 if ((dtdvalid != NULL) || (dtdvalidfpi != NULL)) {
Daniel Veillardcd429612000-10-11 15:57:05 +00001092 xmlDtdPtr dtd;
1093
Daniel Veillard48b2f892001-02-25 16:11:03 +00001094 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001095 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001096 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00001097 if (dtdvalid != NULL)
1098 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
1099 else
1100 dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL);
Daniel Veillard48b2f892001-02-25 16:11:03 +00001101 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001102 endTimer("Parsing DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001103 }
Daniel Veillardcd429612000-10-11 15:57:05 +00001104 if (dtd == NULL) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00001105 if (dtdvalid != NULL)
1106 xmlGenericError(xmlGenericErrorContext,
1107 "Could not parse DTD %s\n", dtdvalid);
1108 else
1109 xmlGenericError(xmlGenericErrorContext,
1110 "Could not parse DTD %s\n", dtdvalidfpi);
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001111 progresult = 2;
Daniel Veillardcd429612000-10-11 15:57:05 +00001112 } else {
Daniel Veillarda37aab82003-06-09 09:10:36 +00001113 xmlValidCtxtPtr cvp;
1114
1115 if ((cvp = xmlNewValidCtxt()) == NULL) {
1116 xmlGenericError(xmlGenericErrorContext,
1117 "Couldn't allocate validation context\n");
1118 exit(-1);
1119 }
1120 cvp->userData = (void *) stderr;
1121 cvp->error = (xmlValidityErrorFunc) fprintf;
1122 cvp->warning = (xmlValidityWarningFunc) fprintf;
1123
Daniel Veillard48b2f892001-02-25 16:11:03 +00001124 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001125 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001126 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00001127 if (!xmlValidateDtd(cvp, doc, dtd)) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00001128 if (dtdvalid != NULL)
1129 xmlGenericError(xmlGenericErrorContext,
1130 "Document %s does not validate against %s\n",
1131 filename, dtdvalid);
1132 else
1133 xmlGenericError(xmlGenericErrorContext,
1134 "Document %s does not validate against %s\n",
1135 filename, dtdvalidfpi);
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001136 progresult = 3;
Daniel Veillardcd429612000-10-11 15:57:05 +00001137 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001138 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001139 endTimer("Validating against DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001140 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00001141 xmlFreeValidCtxt(cvp);
Daniel Veillardcd429612000-10-11 15:57:05 +00001142 xmlFreeDtd(dtd);
1143 }
1144 } else if (postvalid) {
Daniel Veillarda37aab82003-06-09 09:10:36 +00001145 xmlValidCtxtPtr cvp;
1146
1147 if ((cvp = xmlNewValidCtxt()) == NULL) {
1148 xmlGenericError(xmlGenericErrorContext,
1149 "Couldn't allocate validation context\n");
1150 exit(-1);
1151 }
1152
Daniel Veillard48b2f892001-02-25 16:11:03 +00001153 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001154 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001155 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00001156 cvp->userData = (void *) stderr;
1157 cvp->error = (xmlValidityErrorFunc) fprintf;
1158 cvp->warning = (xmlValidityWarningFunc) fprintf;
1159 if (!xmlValidateDocument(cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001160 xmlGenericError(xmlGenericErrorContext,
1161 "Document %s does not validate\n", filename);
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001162 progresult = 3;
Daniel Veillardcd429612000-10-11 15:57:05 +00001163 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001164 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001165 endTimer("Validating");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001166 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00001167 xmlFreeValidCtxt(cvp);
Daniel Veillard71531f32003-02-05 13:19:53 +00001168#ifdef LIBXML_SCHEMAS_ENABLED
1169 } else if (relaxngschemas != NULL) {
1170 xmlRelaxNGValidCtxtPtr ctxt;
1171 int ret;
1172
Daniel Veillard42f12e92003-03-07 18:32:59 +00001173 if ((timing) && (!repeat)) {
1174 startTimer();
1175 }
1176
Daniel Veillard71531f32003-02-05 13:19:53 +00001177 ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
1178 xmlRelaxNGSetValidErrors(ctxt,
1179 (xmlRelaxNGValidityErrorFunc) fprintf,
1180 (xmlRelaxNGValidityWarningFunc) fprintf,
1181 stderr);
1182 ret = xmlRelaxNGValidateDoc(ctxt, doc);
1183 if (ret == 0) {
1184 printf("%s validates\n", filename);
1185 } else if (ret > 0) {
1186 printf("%s fails to validate\n", filename);
1187 } else {
1188 printf("%s validation generated an internal error\n",
1189 filename);
1190 }
1191 xmlRelaxNGFreeValidCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00001192 if ((timing) && (!repeat)) {
1193 endTimer("Validating");
1194 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001195 } else if (wxschemas != NULL) {
1196 xmlSchemaValidCtxtPtr ctxt;
1197 int ret;
1198
1199 if ((timing) && (!repeat)) {
1200 startTimer();
1201 }
1202
1203 ctxt = xmlSchemaNewValidCtxt(wxschemas);
1204 xmlSchemaSetValidErrors(ctxt,
1205 (xmlSchemaValidityErrorFunc) fprintf,
1206 (xmlSchemaValidityWarningFunc) fprintf,
1207 stderr);
1208 ret = xmlSchemaValidateDoc(ctxt, doc);
1209 if (ret == 0) {
1210 printf("%s validates\n", filename);
1211 } else if (ret > 0) {
1212 printf("%s fails to validate\n", filename);
1213 } else {
1214 printf("%s validation generated an internal error\n",
1215 filename);
1216 }
1217 xmlSchemaFreeValidCtxt(ctxt);
1218 if ((timing) && (!repeat)) {
1219 endTimer("Validating");
1220 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001221#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001222 }
1223
1224#ifdef LIBXML_DEBUG_ENABLED
1225 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001226 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001227#endif
1228
1229 /*
1230 * free it.
1231 */
Daniel Veillard48b2f892001-02-25 16:11:03 +00001232 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001233 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001234 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001235 xmlFreeDoc(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +00001236 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001237 endTimer("Freeing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001238 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001239}
1240
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001241/************************************************************************
1242 * *
1243 * Usage and Main *
1244 * *
1245 ************************************************************************/
1246
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00001247static void showVersion(const char *name) {
1248 fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
1249 fprintf(stderr, " compiled with: ");
1250#ifdef LIBXML_FTP_ENABLED
1251 fprintf(stderr, "FTP ");
1252#endif
1253#ifdef LIBXML_HTTP_ENABLED
1254 fprintf(stderr, "HTTP ");
1255#endif
1256#ifdef LIBXML_HTML_ENABLED
1257 fprintf(stderr, "HTML ");
1258#endif
1259#ifdef LIBXML_C14N_ENABLED
1260 fprintf(stderr, "C14N ");
1261#endif
1262#ifdef LIBXML_CATALOG_ENABLED
1263 fprintf(stderr, "Catalog ");
1264#endif
1265#ifdef LIBXML_DOCB_ENABLED
1266 fprintf(stderr, "DocBook ");
1267#endif
1268#ifdef LIBXML_XPATH_ENABLED
1269 fprintf(stderr, "XPath ");
1270#endif
1271#ifdef LIBXML_XPTR_ENABLED
1272 fprintf(stderr, "XPointer ");
1273#endif
1274#ifdef LIBXML_XINCLUDE_ENABLED
1275 fprintf(stderr, "XInclude ");
1276#endif
1277#ifdef LIBXML_ICONV_ENABLED
1278 fprintf(stderr, "Iconv ");
1279#endif
1280#ifdef DEBUG_MEMORY_LOCATION
1281 fprintf(stderr, "MemDebug ");
1282#endif
1283#ifdef LIBXML_UNICODE_ENABLED
1284 fprintf(stderr, "Unicode ");
1285#endif
1286#ifdef LIBXML_REGEXP_ENABLED
1287 fprintf(stderr, "Regexps ");
1288#endif
1289#ifdef LIBXML_AUTOMATA_ENABLED
1290 fprintf(stderr, "Automata ");
1291#endif
1292#ifdef LIBXML_SCHEMAS_ENABLED
1293 fprintf(stderr, "Schemas ");
1294#endif
1295 fprintf(stderr, "\n");
1296}
1297
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001298static void usage(const char *name) {
1299 printf("Usage : %s [options] XMLfiles ...\n", name);
1300 printf("\tParse the XML files and output the result of the parsing\n");
1301 printf("\t--version : display the version of the XML library used\n");
1302#ifdef LIBXML_DEBUG_ENABLED
1303 printf("\t--debug : dump a debug tree of the in-memory document\n");
1304 printf("\t--shell : run a navigating shell\n");
1305 printf("\t--debugent : debug the entities defined in the document\n");
Daniel Veillard8326e732003-01-07 00:19:07 +00001306#else
1307 printf("\t--debug : dump the nodes content when using --stream\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001308#endif
1309 printf("\t--copy : used to test the internal copy implementation\n");
1310 printf("\t--recover : output what was parsable on broken XML documents\n");
1311 printf("\t--noent : substitute entity references by their value\n");
1312 printf("\t--noout : don't output the result tree\n");
Daniel Veillarde8b09e42003-05-13 22:14:13 +00001313 printf("\t--nonet : refuse to fetch DTDs or entities over network\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001314 printf("\t--htmlout : output results as HTML\n");
Daniel Veillard05c13a22001-09-09 08:38:09 +00001315 printf("\t--nowrap : do not put HTML doc wrapper\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001316 printf("\t--valid : validate the document in addition to std well-formed check\n");
1317 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
1318 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
Daniel Veillard66f68e72003-08-18 16:39:51 +00001319 printf("\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001320 printf("\t--timing : print some timings\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001321 printf("\t--output file or -o file: save to a given file\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001322 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
1323 printf("\t--insert : ad-hoc test for valid insertions\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001324#ifdef HAVE_ZLIB_H
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001325 printf("\t--compress : turn on gzip compression of output\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001326#endif
Daniel Veillard89cad532001-10-22 09:46:13 +00001327#ifdef LIBXML_DOCB_ENABLED
1328 printf("\t--sgml : use the DocBook SGML parser\n");
1329#endif
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001330#ifdef LIBXML_HTML_ENABLED
1331 printf("\t--html : use the HTML parser\n");
1332#endif
1333 printf("\t--push : use the push mode of the parser\n");
1334#ifdef HAVE_SYS_MMAN_H
1335 printf("\t--memory : parse from memory\n");
1336#endif
1337 printf("\t--nowarning : do not emit warnings from parser/validator\n");
1338 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
Daniel Veillard90493a92001-08-14 14:12:47 +00001339 printf("\t--format : reformat/reindent the input\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001340 printf("\t--testIO : test user I/O support\n");
1341 printf("\t--encode encoding : output in the given encoding\n");
1342#ifdef LIBXML_CATALOG_ENABLED
Daniel Veillardbd9b0e82001-11-26 10:32:08 +00001343 printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
1344 printf("\t otherwise XML Catalogs starting from \n");
Daniel Veillard3be27512003-01-26 19:49:04 +00001345 printf("\t " XML_XML_DEFAULT_CATALOG " are activated by default\n");
Daniel Veillard05c13a22001-09-09 08:38:09 +00001346 printf("\t--nocatalogs: deactivate all catalogs\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001347#endif
1348 printf("\t--auto : generate a small doc on the fly\n");
1349#ifdef LIBXML_XINCLUDE_ENABLED
1350 printf("\t--xinclude : do XInclude processing\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001351#endif
Daniel Veillardcbaf3992001-12-31 16:16:02 +00001352 printf("\t--loaddtd : fetch external DTD\n");
Daniel Veillard48da9102001-08-07 01:10:10 +00001353 printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
Daniel Veillard29e43992001-12-13 22:21:58 +00001354 printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
Daniel Veillard7704fb12003-01-03 16:19:51 +00001355 printf("\t--stream : use the streaming interface to process very large files\n");
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001356 printf("\t--chkregister : verify the node registration code\n");
Daniel Veillardef4d3bc2003-02-07 12:38:22 +00001357#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard71531f32003-02-05 13:19:53 +00001358 printf("\t--relaxng schema : do RelaxNG validation against the schema\n");
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001359 printf("\t--schema schema : do validation against the WXS schema\n");
Daniel Veillard71531f32003-02-05 13:19:53 +00001360#endif
Daniel Veillarda42f25f2002-01-25 14:15:40 +00001361 printf("\nLibxml project home page: http://xmlsoft.org/\n");
1362 printf("To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001363}
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001364
1365static void registerNode(xmlNodePtr node)
1366{
1367 node->_private = malloc(sizeof(long));
1368 *(long*)node->_private = (long) 0x81726354;
1369}
1370
1371static void deregisterNode(xmlNodePtr node)
1372{
1373 assert(node->_private != NULL);
1374 assert(*(long*)node->_private == (long) 0x81726354);
1375 free(node->_private);
1376}
1377
Daniel Veillard4a6845d2001-01-03 13:32:39 +00001378int
1379main(int argc, char **argv) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00001380 int i, acount;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001381 int files = 0;
Daniel Veillard845cce42002-01-09 11:51:37 +00001382 int version = 0;
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00001383 const char* indent;
1384
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001385 if (argc <= 1) {
1386 usage(argv[0]);
1387 return(1);
1388 }
Daniel Veillardbe803962000-06-28 23:40:59 +00001389 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001390 for (i = 1; i < argc ; i++) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001391 if (!strcmp(argv[i], "-"))
1392 break;
1393
1394 if (argv[i][0] != '-')
1395 continue;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001396 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
1397 debug++;
Daniel Veillard56ada1d2003-01-07 11:17:25 +00001398 else
1399#ifdef LIBXML_DEBUG_ENABLED
1400 if ((!strcmp(argv[i], "-shell")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001401 (!strcmp(argv[i], "--shell"))) {
1402 shell++;
1403 noout = 1;
1404 } else
1405#endif
1406 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
1407 copy++;
1408 else if ((!strcmp(argv[i], "-recover")) ||
1409 (!strcmp(argv[i], "--recover")))
1410 recovery++;
1411 else if ((!strcmp(argv[i], "-noent")) ||
1412 (!strcmp(argv[i], "--noent")))
1413 noent++;
Daniel Veillard4ec885a2001-06-17 10:31:07 +00001414 else if ((!strcmp(argv[i], "-version")) ||
Daniel Veillard845cce42002-01-09 11:51:37 +00001415 (!strcmp(argv[i], "--version"))) {
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00001416 showVersion(argv[0]);
Daniel Veillard845cce42002-01-09 11:51:37 +00001417 version = 1;
1418 } else if ((!strcmp(argv[i], "-noout")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001419 (!strcmp(argv[i], "--noout")))
1420 noout++;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001421 else if ((!strcmp(argv[i], "-o")) ||
1422 (!strcmp(argv[i], "-output")) ||
1423 (!strcmp(argv[i], "--output"))) {
1424 i++;
Daniel Veillard6e4f1c02002-04-09 09:55:20 +00001425 output = argv[i];
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001426 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001427 else if ((!strcmp(argv[i], "-htmlout")) ||
1428 (!strcmp(argv[i], "--htmlout")))
1429 htmlout++;
Daniel Veillard89cad532001-10-22 09:46:13 +00001430#ifdef LIBXML_DOCB_ENABLED
1431 else if ((!strcmp(argv[i], "-sgml")) ||
1432 (!strcmp(argv[i], "--sgml"))) {
1433 sgml++;
1434 }
1435#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001436#ifdef LIBXML_HTML_ENABLED
1437 else if ((!strcmp(argv[i], "-html")) ||
1438 (!strcmp(argv[i], "--html"))) {
1439 html++;
1440 }
1441#endif /* LIBXML_HTML_ENABLED */
1442 else if ((!strcmp(argv[i], "-nowrap")) ||
1443 (!strcmp(argv[i], "--nowrap")))
1444 nowrap++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001445 else if ((!strcmp(argv[i], "-loaddtd")) ||
1446 (!strcmp(argv[i], "--loaddtd")))
1447 loaddtd++;
Daniel Veillard48da9102001-08-07 01:10:10 +00001448 else if ((!strcmp(argv[i], "-dtdattr")) ||
1449 (!strcmp(argv[i], "--dtdattr"))) {
1450 loaddtd++;
1451 dtdattrs++;
1452 } else if ((!strcmp(argv[i], "-valid")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001453 (!strcmp(argv[i], "--valid")))
1454 valid++;
1455 else if ((!strcmp(argv[i], "-postvalid")) ||
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001456 (!strcmp(argv[i], "--postvalid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001457 postvalid++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001458 loaddtd++;
1459 } else if ((!strcmp(argv[i], "-dtdvalid")) ||
Daniel Veillardcd429612000-10-11 15:57:05 +00001460 (!strcmp(argv[i], "--dtdvalid"))) {
1461 i++;
1462 dtdvalid = argv[i];
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001463 loaddtd++;
Daniel Veillard66f68e72003-08-18 16:39:51 +00001464 } else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
1465 (!strcmp(argv[i], "--dtdvalidfpi"))) {
1466 i++;
1467 dtdvalidfpi = argv[i];
1468 loaddtd++;
Daniel Veillardcd429612000-10-11 15:57:05 +00001469 }
Daniel Veillard29e43992001-12-13 22:21:58 +00001470 else if ((!strcmp(argv[i], "-dropdtd")) ||
1471 (!strcmp(argv[i], "--dropdtd")))
1472 dropdtd++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001473 else if ((!strcmp(argv[i], "-insert")) ||
1474 (!strcmp(argv[i], "--insert")))
1475 insert++;
Daniel Veillard48b2f892001-02-25 16:11:03 +00001476 else if ((!strcmp(argv[i], "-timing")) ||
1477 (!strcmp(argv[i], "--timing")))
1478 timing++;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001479 else if ((!strcmp(argv[i], "-auto")) ||
1480 (!strcmp(argv[i], "--auto")))
1481 generate++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001482 else if ((!strcmp(argv[i], "-repeat")) ||
1483 (!strcmp(argv[i], "--repeat")))
1484 repeat++;
1485 else if ((!strcmp(argv[i], "-push")) ||
1486 (!strcmp(argv[i], "--push")))
1487 push++;
Daniel Veillard46e370e2000-07-21 20:32:03 +00001488#ifdef HAVE_SYS_MMAN_H
1489 else if ((!strcmp(argv[i], "-memory")) ||
1490 (!strcmp(argv[i], "--memory")))
1491 memory++;
1492#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +00001493 else if ((!strcmp(argv[i], "-testIO")) ||
1494 (!strcmp(argv[i], "--testIO")))
1495 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00001496#ifdef LIBXML_XINCLUDE_ENABLED
1497 else if ((!strcmp(argv[i], "-xinclude")) ||
1498 (!strcmp(argv[i], "--xinclude")))
1499 xinclude++;
1500#endif
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001501#ifdef HAVE_ZLIB_H
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001502 else if ((!strcmp(argv[i], "-compress")) ||
1503 (!strcmp(argv[i], "--compress"))) {
1504 compress++;
1505 xmlSetCompressMode(9);
1506 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001507#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001508 else if ((!strcmp(argv[i], "-nowarning")) ||
1509 (!strcmp(argv[i], "--nowarning"))) {
1510 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001511 xmlPedanticParserDefault(0);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001512 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001513 else if ((!strcmp(argv[i], "-pedantic")) ||
1514 (!strcmp(argv[i], "--pedantic"))) {
1515 xmlGetWarningsDefaultValue = 1;
1516 xmlPedanticParserDefault(1);
1517 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00001518#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001519 else if ((!strcmp(argv[i], "-debugent")) ||
1520 (!strcmp(argv[i], "--debugent"))) {
1521 debugent++;
1522 xmlParserDebugEntities = 1;
1523 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00001524#endif
Daniel Veillard81418e32001-05-22 15:08:55 +00001525#ifdef LIBXML_CATALOG_ENABLED
1526 else if ((!strcmp(argv[i], "-catalogs")) ||
1527 (!strcmp(argv[i], "--catalogs"))) {
Daniel Veillarde2940dd2001-08-22 00:06:49 +00001528 catalogs++;
1529 } else if ((!strcmp(argv[i], "-nocatalogs")) ||
1530 (!strcmp(argv[i], "--nocatalogs"))) {
1531 nocatalogs++;
Daniel Veillard81418e32001-05-22 15:08:55 +00001532 }
1533#endif
Daniel Veillardbe803962000-06-28 23:40:59 +00001534 else if ((!strcmp(argv[i], "-encode")) ||
1535 (!strcmp(argv[i], "--encode"))) {
1536 i++;
1537 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001538 /*
1539 * OK it's for testing purposes
1540 */
1541 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +00001542 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001543 else if ((!strcmp(argv[i], "-noblanks")) ||
1544 (!strcmp(argv[i], "--noblanks"))) {
1545 noblanks++;
1546 xmlKeepBlanksDefault(0);
Daniel Veillard90493a92001-08-14 14:12:47 +00001547 }
1548 else if ((!strcmp(argv[i], "-format")) ||
1549 (!strcmp(argv[i], "--format"))) {
1550 noblanks++;
1551 format++;
1552 xmlKeepBlanksDefault(0);
Daniel Veillard7704fb12003-01-03 16:19:51 +00001553 }
1554 else if ((!strcmp(argv[i], "-stream")) ||
1555 (!strcmp(argv[i], "--stream"))) {
1556 stream++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001557 }
1558 else if ((!strcmp(argv[i], "-chkregister")) ||
1559 (!strcmp(argv[i], "--chkregister"))) {
1560 chkregister++;
Daniel Veillard71531f32003-02-05 13:19:53 +00001561#ifdef LIBXML_SCHEMAS_ENABLED
1562 } else if ((!strcmp(argv[i], "-relaxng")) ||
1563 (!strcmp(argv[i], "--relaxng"))) {
1564 i++;
1565 relaxng = argv[i];
1566 noent++;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001567 } else if ((!strcmp(argv[i], "-schema")) ||
1568 (!strcmp(argv[i], "--schema"))) {
1569 i++;
1570 schema = argv[i];
1571 noent++;
Daniel Veillard71531f32003-02-05 13:19:53 +00001572#endif
Daniel Veillarde8b09e42003-05-13 22:14:13 +00001573 } else if ((!strcmp(argv[i], "-nonet")) ||
1574 (!strcmp(argv[i], "--nonet"))) {
1575 xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001576 } else {
1577 fprintf(stderr, "Unknown option %s\n", argv[i]);
1578 usage(argv[0]);
1579 return(1);
1580 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001581 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00001582
1583#ifdef LIBXML_CATALOG_ENABLED
1584 if (nocatalogs == 0) {
1585 if (catalogs) {
1586 const char *catal;
1587
1588 catal = getenv("SGML_CATALOG_FILES");
Daniel Veillard6c5f9d12001-08-25 13:33:14 +00001589 if (catal != NULL) {
1590 xmlLoadCatalogs(catal);
1591 } else {
1592 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
1593 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00001594 }
1595 }
1596#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001597
1598 if (chkregister) {
1599 xmlRegisterNodeDefault(registerNode);
1600 xmlDeregisterNodeDefault(deregisterNode);
1601 }
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00001602
1603 indent = getenv("XMLLINT_INDENT");
1604 if(indent != NULL) {
1605 xmlTreeIndentString = indent;
1606 }
1607
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001608
Daniel Veillardd9bad132001-07-23 19:39:43 +00001609 xmlLineNumbersDefault(1);
Daniel Veillard48da9102001-08-07 01:10:10 +00001610 if (loaddtd != 0)
1611 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
1612 if (dtdattrs)
1613 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001614 if (noent != 0) xmlSubstituteEntitiesDefault(1);
1615 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
1616 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001617 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001618 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001619 xmlGenericError(xmlGenericErrorContext,
1620 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
1621 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001622 "<html><head><title>%s output</title></head>\n",
1623 argv[0]);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001624 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001625 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
1626 argv[0]);
1627 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001628
1629#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +00001630 if ((relaxng != NULL) && (stream == 0)) {
Daniel Veillard71531f32003-02-05 13:19:53 +00001631 xmlRelaxNGParserCtxtPtr ctxt;
1632
Daniel Veillardce192eb2003-04-16 15:58:05 +00001633 /* forces loading the DTDs */
1634 xmlLoadExtDtdDefaultValue |= 1;
Daniel Veillard42f12e92003-03-07 18:32:59 +00001635 if (timing) {
1636 startTimer();
1637 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001638 ctxt = xmlRelaxNGNewParserCtxt(relaxng);
1639 xmlRelaxNGSetParserErrors(ctxt,
1640 (xmlRelaxNGValidityErrorFunc) fprintf,
1641 (xmlRelaxNGValidityWarningFunc) fprintf,
1642 stderr);
1643 relaxngschemas = xmlRelaxNGParse(ctxt);
Daniel Veillardce192eb2003-04-16 15:58:05 +00001644 if (relaxngschemas == NULL) {
1645 xmlGenericError(xmlGenericErrorContext,
1646 "Relax-NG schema %s failed to compile\n", relaxng);
1647 relaxng = NULL;
1648 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001649 xmlRelaxNGFreeParserCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00001650 if (timing) {
1651 endTimer("Compiling the schemas");
1652 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001653 } else if ((schema != NULL) && (stream == 0)) {
1654 xmlSchemaParserCtxtPtr ctxt;
1655
1656 if (timing) {
1657 startTimer();
1658 }
1659 ctxt = xmlSchemaNewParserCtxt(schema);
1660 xmlSchemaSetParserErrors(ctxt,
1661 (xmlSchemaValidityErrorFunc) fprintf,
1662 (xmlSchemaValidityWarningFunc) fprintf,
1663 stderr);
1664 wxschemas = xmlSchemaParse(ctxt);
1665 if (wxschemas == NULL) {
1666 xmlGenericError(xmlGenericErrorContext,
1667 "WXS schema %s failed to compile\n", schema);
1668 schema = NULL;
1669 }
1670 xmlSchemaFreeParserCtxt(ctxt);
1671 if (timing) {
1672 endTimer("Compiling the schemas");
1673 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001674 }
1675#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001676 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +00001677 if ((!strcmp(argv[i], "-encode")) ||
1678 (!strcmp(argv[i], "--encode"))) {
1679 i++;
1680 continue;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001681 } else if ((!strcmp(argv[i], "-o")) ||
1682 (!strcmp(argv[i], "-output")) ||
1683 (!strcmp(argv[i], "--output"))) {
1684 i++;
1685 continue;
Daniel Veillardbe803962000-06-28 23:40:59 +00001686 }
Daniel Veillardcd429612000-10-11 15:57:05 +00001687 if ((!strcmp(argv[i], "-dtdvalid")) ||
1688 (!strcmp(argv[i], "--dtdvalid"))) {
1689 i++;
1690 continue;
1691 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00001692 if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
1693 (!strcmp(argv[i], "--dtdvalidfpi"))) {
1694 i++;
1695 continue;
1696 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001697 if ((!strcmp(argv[i], "-relaxng")) ||
1698 (!strcmp(argv[i], "--relaxng"))) {
1699 i++;
1700 continue;
1701 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001702 if ((!strcmp(argv[i], "-schema")) ||
1703 (!strcmp(argv[i], "--schema"))) {
1704 i++;
1705 continue;
1706 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001707 if ((timing) && (repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00001708 startTimer();
Daniel Veillardcbaf3992001-12-31 16:16:02 +00001709 /* Remember file names. "-" means stdin. <sven@zen.org> */
Daniel Veillard4a6845d2001-01-03 13:32:39 +00001710 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001711 if (repeat) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00001712 for (acount = 0;acount < 100 * repeat;acount++)
1713 if (stream != 0)
1714 streamFile(argv[i]);
1715 else
1716 parseAndPrintFile(argv[i]);
1717 } else {
1718 if (stream != 0)
1719 streamFile(argv[i]);
1720 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001721 parseAndPrintFile(argv[i]);
Daniel Veillard7704fb12003-01-03 16:19:51 +00001722 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001723 files ++;
Daniel Veillarda7866932001-12-04 13:14:44 +00001724 if ((timing) && (repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001725 endTimer("100 iterations");
Daniel Veillarda7866932001-12-04 13:14:44 +00001726 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001727 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001728 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001729 if (generate)
1730 parseAndPrintFile(NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001731 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001732 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001733 }
Daniel Veillard845cce42002-01-09 11:51:37 +00001734 if ((files == 0) && (!generate) && (version == 0)) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001735 usage(argv[0]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001736 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001737#ifdef LIBXML_SCHEMAS_ENABLED
1738 if (relaxngschemas != NULL)
1739 xmlRelaxNGFree(relaxngschemas);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001740 if (wxschemas != NULL)
1741 xmlSchemaFree(wxschemas);
Daniel Veillard71531f32003-02-05 13:19:53 +00001742 xmlRelaxNGCleanupTypes();
1743#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001744 xmlCleanupParser();
1745 xmlMemoryDump();
1746
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001747 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001748}
Daniel Veillard88a172f2000-08-04 18:23:10 +00001749