blob: 698170c2c9ed655d699b0b5522b26ef7c438b447 [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 Veillard90bc3712002-03-07 15:12:58 +000034#ifdef HAVE_SYS_TIMEB_H
35#include <sys/timeb.h>
36#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000037
38#ifdef HAVE_SYS_TYPES_H
39#include <sys/types.h>
40#endif
41#ifdef HAVE_SYS_STAT_H
42#include <sys/stat.h>
43#endif
44#ifdef HAVE_FCNTL_H
45#include <fcntl.h>
46#endif
47#ifdef HAVE_UNISTD_H
48#include <unistd.h>
49#endif
Daniel Veillard46e370e2000-07-21 20:32:03 +000050#ifdef HAVE_SYS_MMAN_H
51#include <sys/mman.h>
Daniel Veillard87b95392000-08-12 21:12:04 +000052/* seems needed for Solaris */
53#ifndef MAP_FAILED
54#define MAP_FAILED ((void *) -1)
55#endif
Daniel Veillard46e370e2000-07-21 20:32:03 +000056#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000057#ifdef HAVE_STDLIB_H
58#include <stdlib.h>
59#endif
60#ifdef HAVE_LIBREADLINE
61#include <readline/readline.h>
62#ifdef HAVE_LIBHISTORY
63#include <readline/history.h>
64#endif
65#endif
66
67#include <libxml/xmlmemory.h>
68#include <libxml/parser.h>
69#include <libxml/parserInternals.h>
70#include <libxml/HTMLparser.h>
71#include <libxml/HTMLtree.h>
72#include <libxml/tree.h>
73#include <libxml/xpath.h>
74#include <libxml/debugXML.h>
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +000075#include <libxml/xmlerror.h>
Daniel Veillard9e8bfae2000-11-06 16:43:11 +000076#ifdef LIBXML_XINCLUDE_ENABLED
77#include <libxml/xinclude.h>
78#endif
Daniel Veillard81418e32001-05-22 15:08:55 +000079#ifdef LIBXML_CATALOG_ENABLED
80#include <libxml/catalog.h>
81#endif
Daniel Veillard89cad532001-10-22 09:46:13 +000082#ifdef LIBXML_DOCB_ENABLED
83#include <libxml/DOCBparser.h>
84#endif
Daniel Veillard3c01b1d2001-10-17 15:58:35 +000085#include <libxml/globals.h>
Daniel Veillard7704fb12003-01-03 16:19:51 +000086#include <libxml/xmlreader.h>
Daniel Veillard71531f32003-02-05 13:19:53 +000087#ifdef LIBXML_SCHEMAS_ENABLED
88#include <libxml/relaxng.h>
89#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000090
Daniel Veillard3be27512003-01-26 19:49:04 +000091#ifndef XML_XML_DEFAULT_CATALOG
92#define XML_XML_DEFAULT_CATALOG "file:///etc/xml/catalog"
93#endif
94
Daniel Veillardce8b83b2000-04-05 18:38:42 +000095#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +000096static int shell = 0;
97static int debugent = 0;
98#endif
Daniel Veillard8326e732003-01-07 00:19:07 +000099static int debug = 0;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000100static int copy = 0;
101static int recovery = 0;
102static int noent = 0;
103static int noout = 0;
104static int nowrap = 0;
105static int valid = 0;
106static int postvalid = 0;
Daniel Veillardcd429612000-10-11 15:57:05 +0000107static char * dtdvalid = NULL;
Daniel Veillard71531f32003-02-05 13:19:53 +0000108#ifdef LIBXML_SCHEMAS_ENABLED
109static char * relaxng = NULL;
110static xmlRelaxNGPtr relaxngschemas = NULL;
111#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000112static int repeat = 0;
113static int insert = 0;
114static int compress = 0;
Daniel Veillard89cad532001-10-22 09:46:13 +0000115#ifdef LIBXML_DOCB_ENABLED
116static int sgml = 0;
117#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000118static int html = 0;
119static int htmlout = 0;
120static int push = 0;
Daniel Veillard46e370e2000-07-21 20:32:03 +0000121#ifdef HAVE_SYS_MMAN_H
122static int memory = 0;
123#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000124static int noblanks = 0;
Daniel Veillard90493a92001-08-14 14:12:47 +0000125static int format = 0;
Daniel Veillard5e873c42000-04-12 13:27:38 +0000126static int testIO = 0;
Daniel Veillardbe803962000-06-28 23:40:59 +0000127static char *encoding = NULL;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000128#ifdef LIBXML_XINCLUDE_ENABLED
129static int xinclude = 0;
130#endif
Daniel Veillard48da9102001-08-07 01:10:10 +0000131static int dtdattrs = 0;
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000132static int loaddtd = 0;
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000133static int progresult = 0;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000134static int timing = 0;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000135static int generate = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000136static int dropdtd = 0;
Daniel Veillarde2940dd2001-08-22 00:06:49 +0000137#ifdef LIBXML_CATALOG_ENABLED
138static int catalogs = 0;
139static int nocatalogs = 0;
140#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +0000141static int stream = 0;
Daniel Veillard8a1b1852003-01-05 22:37:17 +0000142static int chkregister = 0;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +0000143static const char *output = NULL;
144
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000145
Daniel Veillard01db67c2001-12-18 07:09:59 +0000146/*
147 * Internal timing routines to remove the necessity to have unix-specific
148 * function calls
149 */
150
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000151#ifndef HAVE_GETTIMEOFDAY
152#ifdef HAVE_SYS_TIMEB_H
153#ifdef HAVE_SYS_TIME_H
154#ifdef HAVE_FTIME
155
Daniel Veillard01c13b52002-12-10 15:19:08 +0000156static int
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000157my_gettimeofday(struct timeval *tvp, void *tzp)
158{
159 struct timeb timebuffer;
160
161 ftime(&timebuffer);
162 if (tvp) {
163 tvp->tv_sec = timebuffer.time;
164 tvp->tv_usec = timebuffer.millitm * 1000L;
165 }
166 return (0);
167}
168#define HAVE_GETTIMEOFDAY 1
169#define gettimeofday my_gettimeofday
170
171#endif /* HAVE_FTIME */
172#endif /* HAVE_SYS_TIME_H */
173#endif /* HAVE_SYS_TIMEB_H */
174#endif /* !HAVE_GETTIMEOFDAY */
175
Daniel Veillard01db67c2001-12-18 07:09:59 +0000176#if defined(HAVE_GETTIMEOFDAY)
177static struct timeval begin, end;
178
179/*
180 * startTimer: call where you want to start timing
181 */
182static void
183startTimer(void)
184{
185 gettimeofday(&begin, NULL);
186}
187
188/*
189 * endTimer: call where you want to stop timing and to print out a
190 * message about the timing performed; format is a printf
191 * type argument
192 */
193static void
Daniel Veillard118aed72002-09-24 14:13:13 +0000194endTimer(const char *fmt, ...)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000195{
196 long msec;
197 va_list ap;
198
199 gettimeofday(&end, NULL);
200 msec = end.tv_sec - begin.tv_sec;
201 msec *= 1000;
202 msec += (end.tv_usec - begin.tv_usec) / 1000;
203
204#ifndef HAVE_STDARG_H
205#error "endTimer required stdarg functions"
206#endif
Daniel Veillard118aed72002-09-24 14:13:13 +0000207 va_start(ap, fmt);
208 vfprintf(stderr, fmt, ap);
Daniel Veillard01db67c2001-12-18 07:09:59 +0000209 va_end(ap);
210
211 fprintf(stderr, " took %ld ms\n", msec);
212}
213#elif defined(HAVE_TIME_H)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000214/*
215 * No gettimeofday function, so we have to make do with calling clock.
216 * This is obviously less accurate, but there's little we can do about
217 * that.
218 */
Daniel Veillard90bc3712002-03-07 15:12:58 +0000219#ifndef CLOCKS_PER_SEC
220#define CLOCKS_PER_SEC 100
221#endif
Daniel Veillard01db67c2001-12-18 07:09:59 +0000222
223static clock_t begin, end;
224static void
225startTimer(void)
226{
227 begin = clock();
228}
229static void
230endTimer(const char *fmt, ...)
231{
232 long msec;
233 va_list ap;
234
235 end = clock();
236 msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
237
238#ifndef HAVE_STDARG_H
239#error "endTimer required stdarg functions"
240#endif
241 va_start(ap, fmt);
242 vfprintf(stderr, fmt, ap);
243 va_end(ap);
244 fprintf(stderr, " took %ld ms\n", msec);
245}
246#else
247
248/*
249 * We don't have a gettimeofday or time.h, so we just don't do timing
250 */
251static void
252startTimer(void)
253{
254 /*
255 * Do nothing
256 */
257}
258static void
259endTimer(char *format, ...)
260{
261 /*
262 * We cannot do anything because we don't have a timing function
263 */
264#ifdef HAVE_STDARG_H
265 va_start(ap, format);
266 vfprintf(stderr, format, ap);
267 va_end(ap);
268 fprintf(stderr, " was not timed\n", msec);
269#else
270 /* We don't have gettimeofday, time or stdarg.h, what crazy world is
271 * this ?!
272 */
273#endif
274}
275#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000276/************************************************************************
277 * *
278 * HTML ouput *
279 * *
280 ************************************************************************/
281char buffer[50000];
282
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000283static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000284xmlHTMLEncodeSend(void) {
285 char *result;
286
287 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
288 if (result) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000289 xmlGenericError(xmlGenericErrorContext, "%s", result);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000290 xmlFree(result);
291 }
292 buffer[0] = 0;
293}
294
295/**
296 * xmlHTMLPrintFileInfo:
297 * @input: an xmlParserInputPtr input
298 *
299 * Displays the associated file and line informations for the current input
300 */
301
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000302static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000303xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000304 int len;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000305 xmlGenericError(xmlGenericErrorContext, "<p>");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000306
307 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000308 if (input != NULL) {
309 if (input->filename) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000310 snprintf(&buffer[len], sizeof(buffer) - len, "%s:%d: ", input->filename,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000311 input->line);
312 } else {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000313 snprintf(&buffer[len], sizeof(buffer) - len, "Entity: line %d: ", input->line);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000314 }
315 }
316 xmlHTMLEncodeSend();
317}
318
319/**
320 * xmlHTMLPrintFileContext:
321 * @input: an xmlParserInputPtr input
322 *
323 * Displays current context within the input content for error tracking
324 */
325
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000326static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000327xmlHTMLPrintFileContext(xmlParserInputPtr input) {
328 const xmlChar *cur, *base;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000329 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000330 int n;
331
332 if (input == NULL) return;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000333 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000334 cur = input->cur;
335 base = input->base;
336 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
337 cur--;
338 }
339 n = 0;
340 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
341 cur--;
342 if ((*cur == '\n') || (*cur == '\r')) cur++;
343 base = cur;
344 n = 0;
345 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000346 len = strlen(buffer);
347 snprintf(&buffer[len], sizeof(buffer) - len, "%c",
348 (unsigned char) *cur++);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000349 n++;
350 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000351 len = strlen(buffer);
352 snprintf(&buffer[len], sizeof(buffer) - len, "\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000353 cur = input->cur;
354 while ((*cur == '\n') || (*cur == '\r'))
355 cur--;
356 n = 0;
357 while ((cur != base) && (n++ < 80)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000358 len = strlen(buffer);
359 snprintf(&buffer[len], sizeof(buffer) - len, " ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000360 base++;
361 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000362 len = strlen(buffer);
363 snprintf(&buffer[len], sizeof(buffer) - len, "^\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000364 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000365 xmlGenericError(xmlGenericErrorContext, "</pre>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000366}
367
368/**
369 * xmlHTMLError:
370 * @ctx: an XML parser context
371 * @msg: the message to display/transmit
372 * @...: extra parameters for the message display
373 *
374 * Display and format an error messages, gives file, line, position and
375 * extra parameters.
376 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000377static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000378xmlHTMLError(void *ctx, const char *msg, ...)
379{
380 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
381 xmlParserInputPtr input;
382 xmlParserInputPtr cur = NULL;
383 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000384 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000385
386 buffer[0] = 0;
387 input = ctxt->input;
388 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
389 cur = input;
390 input = ctxt->inputTab[ctxt->inputNr - 2];
391 }
392
393 xmlHTMLPrintFileInfo(input);
394
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000395 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000396 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000397 len = strlen(buffer);
398 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000399 va_end(args);
400 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000401 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000402
403 xmlHTMLPrintFileContext(input);
404 xmlHTMLEncodeSend();
405}
406
407/**
408 * xmlHTMLWarning:
409 * @ctx: an XML parser context
410 * @msg: the message to display/transmit
411 * @...: extra parameters for the message display
412 *
413 * Display and format a warning messages, gives file, line, position and
414 * extra parameters.
415 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000416static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000417xmlHTMLWarning(void *ctx, const char *msg, ...)
418{
419 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
420 xmlParserInputPtr input;
421 xmlParserInputPtr cur = NULL;
422 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000423 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000424
425 buffer[0] = 0;
426 input = ctxt->input;
427 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
428 cur = input;
429 input = ctxt->inputTab[ctxt->inputNr - 2];
430 }
431
432
433 xmlHTMLPrintFileInfo(input);
434
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000435 xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000436 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000437 len = strlen(buffer);
438 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000439 va_end(args);
440 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000441 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000442
443 xmlHTMLPrintFileContext(input);
444 xmlHTMLEncodeSend();
445}
446
447/**
448 * xmlHTMLValidityError:
449 * @ctx: an XML parser context
450 * @msg: the message to display/transmit
451 * @...: extra parameters for the message display
452 *
453 * Display and format an validity error messages, gives file,
454 * line, position and extra parameters.
455 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000456static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000457xmlHTMLValidityError(void *ctx, const char *msg, ...)
458{
459 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
460 xmlParserInputPtr input;
461 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000462 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000463
464 buffer[0] = 0;
465 input = ctxt->input;
466 if ((input->filename == NULL) && (ctxt->inputNr > 1))
467 input = ctxt->inputTab[ctxt->inputNr - 2];
468
469 xmlHTMLPrintFileInfo(input);
470
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000471 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000472 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000473 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000474 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000475 va_end(args);
476 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000477 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000478
479 xmlHTMLPrintFileContext(input);
480 xmlHTMLEncodeSend();
481}
482
483/**
484 * xmlHTMLValidityWarning:
485 * @ctx: an XML parser context
486 * @msg: the message to display/transmit
487 * @...: extra parameters for the message display
488 *
489 * Display and format a validity warning messages, gives file, line,
490 * position and extra parameters.
491 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000492static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000493xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
494{
495 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
496 xmlParserInputPtr input;
497 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000498 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000499
500 buffer[0] = 0;
501 input = ctxt->input;
502 if ((input->filename == NULL) && (ctxt->inputNr > 1))
503 input = ctxt->inputTab[ctxt->inputNr - 2];
504
505 xmlHTMLPrintFileInfo(input);
506
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000507 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000508 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000509 len = strlen(buffer);
510 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000511 va_end(args);
512 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000513 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000514
515 xmlHTMLPrintFileContext(input);
516 xmlHTMLEncodeSend();
517}
518
519/************************************************************************
520 * *
521 * Shell Interface *
522 * *
523 ************************************************************************/
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000524#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000525/**
526 * xmlShellReadline:
527 * @prompt: the prompt value
528 *
529 * Read a string
530 *
531 * Returns a pointer to it or NULL on EOF the caller is expected to
532 * free the returned string.
533 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000534static char *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000535xmlShellReadline(char *prompt) {
536#ifdef HAVE_LIBREADLINE
537 char *line_read;
538
539 /* Get a line from the user. */
540 line_read = readline (prompt);
541
542 /* If the line has any text in it, save it on the history. */
543 if (line_read && *line_read)
544 add_history (line_read);
545
546 return (line_read);
547#else
548 char line_read[501];
Daniel Veillard29e43992001-12-13 22:21:58 +0000549 char *ret;
550 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000551
552 if (prompt != NULL)
553 fprintf(stdout, "%s", prompt);
554 if (!fgets(line_read, 500, stdin))
555 return(NULL);
556 line_read[500] = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000557 len = strlen(line_read);
558 ret = (char *) malloc(len + 1);
559 if (ret != NULL) {
560 memcpy (ret, line_read, len + 1);
561 }
562 return(ret);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000563#endif
564}
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000565#endif /* LIBXML_DEBUG_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000566
567/************************************************************************
568 * *
Daniel Veillard5e873c42000-04-12 13:27:38 +0000569 * I/O Interfaces *
570 * *
571 ************************************************************************/
572
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000573static int myRead(FILE *f, char * buf, int len) {
574 return(fread(buf, 1, len, f));
Daniel Veillard5e873c42000-04-12 13:27:38 +0000575}
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000576static void myClose(FILE *f) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000577 if (f != stdin) {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000578 fclose(f);
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000579 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000580}
581
582/************************************************************************
583 * *
Daniel Veillard7704fb12003-01-03 16:19:51 +0000584 * Stream Test processing *
585 * *
586 ************************************************************************/
587static int count = 0;
588static int elem, attrs;
589
590static void processNode(xmlTextReaderPtr reader) {
Daniel Veillarde59494f2003-01-04 16:35:29 +0000591 xmlChar *name, *value;
Daniel Veillard7704fb12003-01-03 16:19:51 +0000592
Daniel Veillarde59494f2003-01-04 16:35:29 +0000593 name = xmlTextReaderName(reader);
594 if (name == NULL)
595 name = xmlStrdup(BAD_CAST "--");
Daniel Veillard99737f52003-03-22 14:55:50 +0000596
Daniel Veillarde59494f2003-01-04 16:35:29 +0000597 value = xmlTextReaderValue(reader);
Daniel Veillard7704fb12003-01-03 16:19:51 +0000598
Daniel Veillard99737f52003-03-22 14:55:50 +0000599 printf("%d %d %s %d %d",
Daniel Veillarde59494f2003-01-04 16:35:29 +0000600 xmlTextReaderDepth(reader),
601 xmlTextReaderNodeType(reader),
602 name,
Daniel Veillard99737f52003-03-22 14:55:50 +0000603 xmlTextReaderIsEmptyElement(reader),
604 xmlTextReaderHasValue(reader));
Daniel Veillarde59494f2003-01-04 16:35:29 +0000605 xmlFree(name);
606 if (value == NULL)
607 printf("\n");
608 else {
609 printf(" %s\n", value);
610 xmlFree(value);
Daniel Veillard7704fb12003-01-03 16:19:51 +0000611 }
612}
613
614static void streamFile(char *filename) {
615 xmlTextReaderPtr reader;
616 int ret;
617
618 if (count) {
619 elem = 0;
620 attrs = 0;
621 }
622
623 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);
629 if (relaxng != NULL) {
630 if (timing) {
631 startTimer();
632 }
633 ret = xmlTextReaderRelaxNGValidate(reader, relaxng);
634 if (ret < 0) {
635 xmlGenericError(xmlGenericErrorContext,
636 "Relax-NG schema %s failed to compile\n", relaxng);
637 relaxng = NULL;
638 }
639 if (timing) {
640 endTimer("Compiling the schemas");
641 }
642 }
Daniel Veillard7704fb12003-01-03 16:19:51 +0000643
644 /*
645 * Process all nodes in sequence
646 */
Daniel Veillardce192eb2003-04-16 15:58:05 +0000647 if (timing) {
648 startTimer();
649 }
Daniel Veillard7704fb12003-01-03 16:19:51 +0000650 ret = xmlTextReaderRead(reader);
651 while (ret == 1) {
652 if (debug)
653 processNode(reader);
654 ret = xmlTextReaderRead(reader);
655 }
Daniel Veillardce192eb2003-04-16 15:58:05 +0000656 if (timing) {
657 if ((valid) || (relaxng != NULL))
658 endTimer("Parsing and validating");
659 else
660 endTimer("Parsing");
661 }
Daniel Veillard7704fb12003-01-03 16:19:51 +0000662
Daniel Veillardf6bad792003-04-11 19:38:54 +0000663 if (valid) {
664 if (xmlTextReaderIsValid(reader) != 1) {
665 xmlGenericError(xmlGenericErrorContext,
666 "Document %s does not validate\n", filename);
667 progresult = 3;
668 }
669 }
Daniel Veillardf4e55762003-04-15 23:32:22 +0000670 if (relaxng != NULL) {
671 if (xmlTextReaderIsValid(reader) != 1) {
672 printf("%s fails to validate\n", filename);
673 progresult = 3;
674 } else {
675 printf("%s validates\n", filename);
676 }
677 }
Daniel Veillard7704fb12003-01-03 16:19:51 +0000678 /*
679 * Done, cleanup and status
680 */
681 xmlFreeTextReader(reader);
682 if (ret != 0) {
683 printf("%s : failed to parse\n", filename);
Daniel Veillardf6bad792003-04-11 19:38:54 +0000684 progresult = 1;
Daniel Veillard7704fb12003-01-03 16:19:51 +0000685 }
686 } else {
687 fprintf(stderr, "Unable to open %s\n", filename);
Daniel Veillardf6bad792003-04-11 19:38:54 +0000688 progresult = 1;
Daniel Veillard7704fb12003-01-03 16:19:51 +0000689 }
690}
691
692/************************************************************************
693 * *
694 * Tree Test processing *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000695 * *
696 ************************************************************************/
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000697static void parseAndPrintFile(char *filename) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000698 xmlDocPtr doc = NULL, tmp;
699
Daniel Veillard48b2f892001-02-25 16:11:03 +0000700 if ((timing) && (!repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +0000701 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +0000702
703
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000704 if (filename == NULL) {
705 if (generate) {
706 xmlNodePtr n;
707
708 doc = xmlNewDoc(BAD_CAST "1.0");
709 n = xmlNewNode(NULL, BAD_CAST "info");
710 xmlNodeSetContent(n, BAD_CAST "abc");
711 xmlDocSetRootElement(doc, n);
712 }
713 }
Daniel Veillard89cad532001-10-22 09:46:13 +0000714#ifdef LIBXML_DOCB_ENABLED
715 /*
716 * build an SGML tree from a string;
717 */
718 else if ((sgml) && (push)) {
719 FILE *f;
720
721 f = fopen(filename, "r");
722 if (f != NULL) {
723 int res, size = 3;
724 char chars[4096];
725 docbParserCtxtPtr ctxt;
726
727 /* if (repeat) */
728 size = 4096;
729 res = fread(chars, 1, 4, f);
730 if (res > 0) {
731 ctxt = docbCreatePushParserCtxt(NULL, NULL,
732 chars, res, filename, 0);
733 while ((res = fread(chars, 1, size, f)) > 0) {
734 docbParseChunk(ctxt, chars, res, 0);
735 }
736 docbParseChunk(ctxt, chars, 0, 1);
737 doc = ctxt->myDoc;
738 docbFreeParserCtxt(ctxt);
739 }
740 fclose(f);
741 }
742 } else if (sgml) {
743 doc = docbParseFile(filename, NULL);
744 }
745#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000746#ifdef LIBXML_HTML_ENABLED
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000747 else if (html) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000748 doc = htmlParseFile(filename, NULL);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000749 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000750#endif /* LIBXML_HTML_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000751 else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000752 /*
753 * build an XML tree from a string;
754 */
755 if (push) {
756 FILE *f;
757
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000758 /* '-' Usually means stdin -<sven@zen.org> */
759 if ((filename[0] == '-') && (filename[1] == 0)) {
760 f = stdin;
761 } else {
762 f = fopen(filename, "r");
763 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000764 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +0000765 int ret;
Daniel Veillarda880b122003-04-21 21:36:41 +0000766 int res, size = 1024;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000767 char chars[1024];
768 xmlParserCtxtPtr ctxt;
769
Daniel Veillarda880b122003-04-21 21:36:41 +0000770 /* if (repeat) size = 1024; */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000771 res = fread(chars, 1, 4, f);
772 if (res > 0) {
773 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
774 chars, res, filename);
775 while ((res = fread(chars, 1, size, f)) > 0) {
776 xmlParseChunk(ctxt, chars, res, 0);
777 }
778 xmlParseChunk(ctxt, chars, 0, 1);
779 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +0000780 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000781 xmlFreeParserCtxt(ctxt);
Daniel Veillarde715dd22000-08-29 18:29:38 +0000782 if (!ret) {
783 xmlFreeDoc(doc);
784 doc = NULL;
785 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000786 }
787 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000788 } else if (testIO) {
789 int ret;
790 FILE *f;
791
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000792 /* '-' Usually means stdin -<sven@zen.org> */
793 if ((filename[0] == '-') && (filename[1] == 0)) {
794 f = stdin;
795 } else {
796 f = fopen(filename, "r");
797 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000798 if (f != NULL) {
799 xmlParserCtxtPtr ctxt;
800
801 ctxt = xmlCreateIOParserCtxt(NULL, NULL,
802 (xmlInputReadCallback) myRead,
803 (xmlInputCloseCallback) myClose,
804 f, XML_CHAR_ENCODING_NONE);
805 xmlParseDocument(ctxt);
806
807 ret = ctxt->wellFormed;
808 doc = ctxt->myDoc;
809 xmlFreeParserCtxt(ctxt);
810 if (!ret) {
811 xmlFreeDoc(doc);
812 doc = NULL;
813 }
814 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000815 } else if (recovery) {
816 doc = xmlRecoverFile(filename);
817 } else if (htmlout) {
818 int ret;
819 xmlParserCtxtPtr ctxt;
820 xmlSAXHandler silent, *old;
821
822 ctxt = xmlCreateFileParserCtxt(filename);
Daniel Veillard88a172f2000-08-04 18:23:10 +0000823
824 if (ctxt == NULL) {
Daniel Veillardcbaf3992001-12-31 16:16:02 +0000825 /* If xmlCreateFileParserCtxt() return NULL something
Daniel Veillard88a172f2000-08-04 18:23:10 +0000826 strange happened so we don't want to do anything. Do
827 we want to print an error message here?
828 <sven@zen.org> */
Daniel Veillard7ebb1ee2000-08-04 18:24:45 +0000829 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000830 } else {
831 memcpy(&silent, ctxt->sax, sizeof(silent));
832 old = ctxt->sax;
833 silent.error = xmlHTMLError;
834 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000835 silent.warning = xmlHTMLWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000836 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000837 silent.warning = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000838 silent.fatalError = xmlHTMLError;
839 ctxt->sax = &silent;
840 ctxt->vctxt.error = xmlHTMLValidityError;
841 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000842 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000843 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000844 ctxt->vctxt.warning = NULL;
845
Daniel Veillard88a172f2000-08-04 18:23:10 +0000846 xmlParseDocument(ctxt);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000847
Daniel Veillard88a172f2000-08-04 18:23:10 +0000848 ret = ctxt->wellFormed;
849 doc = ctxt->myDoc;
850 ctxt->sax = old;
851 xmlFreeParserCtxt(ctxt);
852 if (!ret) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000853 xmlFreeDoc(doc);
854 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000855 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000856 }
Daniel Veillard46e370e2000-07-21 20:32:03 +0000857#ifdef HAVE_SYS_MMAN_H
858 } else if (memory) {
859 int fd;
860 struct stat info;
861 const char *base;
862 if (stat(filename, &info) < 0)
863 return;
864 if ((fd = open(filename, O_RDONLY)) < 0)
865 return;
866 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillard29579362000-08-14 17:57:48 +0000867 if (base == (void *) MAP_FAILED)
Daniel Veillard46e370e2000-07-21 20:32:03 +0000868 return;
869
870 doc = xmlParseMemory((char *) base, info.st_size);
871 munmap((char *) base, info.st_size);
872#endif
Daniel Veillardea7751d2002-12-20 00:16:24 +0000873 } else if (valid) {
874 int ret;
875 xmlParserCtxtPtr ctxt;
876
877 ctxt = xmlCreateFileParserCtxt(filename);
878
879 if (ctxt == NULL) {
880 doc = NULL;
881 } else {
882 xmlParseDocument(ctxt);
883 if (ctxt->valid == 0)
884 progresult = 4;
885 ret = ctxt->wellFormed;
886 doc = ctxt->myDoc;
887 xmlFreeParserCtxt(ctxt);
888 if (!ret) {
889 xmlFreeDoc(doc);
890 doc = NULL;
891 }
892 }
893 } else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000894 doc = xmlParseFile(filename);
Daniel Veillardea7751d2002-12-20 00:16:24 +0000895 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000896 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000897
Daniel Veillard88a172f2000-08-04 18:23:10 +0000898 /*
899 * If we don't have a document we might as well give up. Do we
900 * want an error message here? <sven@zen.org> */
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000901 if (doc == NULL) {
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000902 progresult = 1;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000903 return;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000904 }
905
Daniel Veillard48b2f892001-02-25 16:11:03 +0000906 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +0000907 endTimer("Parsing");
Daniel Veillard48b2f892001-02-25 16:11:03 +0000908 }
909
Daniel Veillard29e43992001-12-13 22:21:58 +0000910 /*
911 * Remove DOCTYPE nodes
912 */
913 if (dropdtd) {
914 xmlDtdPtr dtd;
915
916 dtd = xmlGetIntSubset(doc);
917 if (dtd != NULL) {
918 xmlUnlinkNode((xmlNodePtr)dtd);
919 xmlFreeDtd(dtd);
920 }
921 }
922
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000923#ifdef LIBXML_XINCLUDE_ENABLED
Daniel Veillard48b2f892001-02-25 16:11:03 +0000924 if (xinclude) {
925 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +0000926 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +0000927 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000928 xmlXIncludeProcess(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000929 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +0000930 endTimer("Xinclude processing");
Daniel Veillard48b2f892001-02-25 16:11:03 +0000931 }
932 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000933#endif
Daniel Veillard88a172f2000-08-04 18:23:10 +0000934
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000935#ifdef LIBXML_DEBUG_ENABLED
936 /*
Daniel Veillardcbaf3992001-12-31 16:16:02 +0000937 * shell interaction
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000938 */
939 if (shell)
940 xmlShell(doc, filename, xmlShellReadline, stdout);
941#endif
942
943 /*
944 * test intermediate copy if needed.
945 */
946 if (copy) {
947 tmp = doc;
948 doc = xmlCopyDoc(doc, 1);
949 xmlFreeDoc(tmp);
950 }
951
952 if ((insert) && (!html)) {
953 const xmlChar* list[256];
954 int nb, i;
955 xmlNodePtr node;
956
957 if (doc->children != NULL) {
958 node = doc->children;
959 while ((node != NULL) && (node->last == NULL)) node = node->next;
960 if (node != NULL) {
961 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
962 if (nb < 0) {
963 printf("could not get valid list of elements\n");
964 } else if (nb == 0) {
MDT 2001 John Fleckbbb9e432001-09-24 03:08:43 +0000965 printf("No element can be inserted under root\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000966 } else {
MDT 2001 John Fleckbbb9e432001-09-24 03:08:43 +0000967 printf("%d element types can be inserted under root:\n",
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000968 nb);
969 for (i = 0;i < nb;i++) {
Daniel Veillard8a1b1852003-01-05 22:37:17 +0000970 printf("%s\n", (char *) list[i]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000971 }
972 }
973 }
974 }
975 }else if (noout == 0) {
976 /*
977 * print it.
978 */
979#ifdef LIBXML_DEBUG_ENABLED
980 if (!debug) {
981#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +0000982 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +0000983 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +0000984 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +0000985#ifdef HAVE_SYS_MMAN_H
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000986 if (memory) {
987 xmlChar *result;
988 int len;
989
990 if (encoding != NULL) {
Daniel Veillardd536f702001-11-08 17:32:47 +0000991 if ( format ) {
992 xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
993 } else {
994 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
995 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000996 } else {
Daniel Veillard90493a92001-08-14 14:12:47 +0000997 if (format)
998 xmlDocDumpFormatMemory(doc, &result, &len, 1);
999 else
1000 xmlDocDumpMemory(doc, &result, &len);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001001 }
1002 if (result == NULL) {
1003 fprintf(stderr, "Failed to save\n");
1004 } else {
1005 write(1, result, len);
1006 xmlFree(result);
1007 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +00001008 } else
1009#endif /* HAVE_SYS_MMAN_H */
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001010 if (compress) {
1011 xmlSaveFile(output ? output : "-", doc);
1012 }
Daniel Veillardd536f702001-11-08 17:32:47 +00001013 else if (encoding != NULL) {
1014 if ( format ) {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001015 xmlSaveFormatFileEnc(output ? output : "-", doc, encoding, 1);
1016 }
Daniel Veillardd536f702001-11-08 17:32:47 +00001017 else {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001018 xmlSaveFileEnc(output ? output : "-", doc, encoding);
Daniel Veillardd536f702001-11-08 17:32:47 +00001019 }
1020 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001021 else if (format) {
1022 xmlSaveFormatFile(output ? output : "-", doc, 1);
1023 }
1024 else {
1025 FILE *out;
1026 if (output == NULL)
1027 out = stdout;
1028 else {
1029 out = fopen(output,"wb");
1030 }
1031 xmlDocDump(out, doc);
1032
1033 if (output)
1034 fclose(out);
1035 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001036 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001037 endTimer("Saving");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001038 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001039#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001040 } else {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001041 FILE *out;
1042 if (output == NULL)
1043 out = stdout;
1044 else {
1045 out = fopen(output,"wb");
1046 }
1047 xmlDebugDumpDocument(out, doc);
1048
1049 if (output)
1050 fclose(out);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001051 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001052#endif
1053 }
1054
1055 /*
1056 * A posteriori validation test
1057 */
Daniel Veillardcd429612000-10-11 15:57:05 +00001058 if (dtdvalid != NULL) {
1059 xmlDtdPtr dtd;
1060
Daniel Veillard48b2f892001-02-25 16:11:03 +00001061 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001062 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001063 }
Daniel Veillardcd429612000-10-11 15:57:05 +00001064 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
Daniel Veillard48b2f892001-02-25 16:11:03 +00001065 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001066 endTimer("Parsing DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001067 }
Daniel Veillardcd429612000-10-11 15:57:05 +00001068 if (dtd == NULL) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001069 xmlGenericError(xmlGenericErrorContext,
1070 "Could not parse DTD %s\n", dtdvalid);
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001071 progresult = 2;
Daniel Veillardcd429612000-10-11 15:57:05 +00001072 } else {
1073 xmlValidCtxt cvp;
Daniel Veillard48b2f892001-02-25 16:11:03 +00001074 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001075 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001076 }
Daniel Veillard01db67c2001-12-18 07:09:59 +00001077 cvp.userData = (void *) stderr;
1078 cvp.error = (xmlValidityErrorFunc) fprintf;
1079 cvp.warning = (xmlValidityWarningFunc) fprintf;
Daniel Veillardcd429612000-10-11 15:57:05 +00001080 if (!xmlValidateDtd(&cvp, doc, dtd)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001081 xmlGenericError(xmlGenericErrorContext,
1082 "Document %s does not validate against %s\n",
Daniel Veillardcd429612000-10-11 15:57:05 +00001083 filename, dtdvalid);
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001084 progresult = 3;
Daniel Veillardcd429612000-10-11 15:57:05 +00001085 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001086 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001087 endTimer("Validating against DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001088 }
Daniel Veillardcd429612000-10-11 15:57:05 +00001089 xmlFreeDtd(dtd);
1090 }
1091 } else if (postvalid) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001092 xmlValidCtxt cvp;
Daniel Veillard48b2f892001-02-25 16:11:03 +00001093 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001094 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001095 }
Daniel Veillardb7664f42001-08-19 13:00:43 +00001096 cvp.userData = (void *) stderr;
1097 cvp.error = (xmlValidityErrorFunc) fprintf;
1098 cvp.warning = (xmlValidityWarningFunc) fprintf;
Daniel Veillardcd429612000-10-11 15:57:05 +00001099 if (!xmlValidateDocument(&cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001100 xmlGenericError(xmlGenericErrorContext,
1101 "Document %s does not validate\n", filename);
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001102 progresult = 3;
Daniel Veillardcd429612000-10-11 15:57:05 +00001103 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001104 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001105 endTimer("Validating");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001106 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001107#ifdef LIBXML_SCHEMAS_ENABLED
1108 } else if (relaxngschemas != NULL) {
1109 xmlRelaxNGValidCtxtPtr ctxt;
1110 int ret;
1111
Daniel Veillard42f12e92003-03-07 18:32:59 +00001112 if ((timing) && (!repeat)) {
1113 startTimer();
1114 }
1115
Daniel Veillard71531f32003-02-05 13:19:53 +00001116 ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
1117 xmlRelaxNGSetValidErrors(ctxt,
1118 (xmlRelaxNGValidityErrorFunc) fprintf,
1119 (xmlRelaxNGValidityWarningFunc) fprintf,
1120 stderr);
1121 ret = xmlRelaxNGValidateDoc(ctxt, doc);
1122 if (ret == 0) {
1123 printf("%s validates\n", filename);
1124 } else if (ret > 0) {
1125 printf("%s fails to validate\n", filename);
1126 } else {
1127 printf("%s validation generated an internal error\n",
1128 filename);
1129 }
1130 xmlRelaxNGFreeValidCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00001131 if ((timing) && (!repeat)) {
1132 endTimer("Validating");
1133 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001134#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001135 }
1136
1137#ifdef LIBXML_DEBUG_ENABLED
1138 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001139 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001140#endif
1141
1142 /*
1143 * free it.
1144 */
Daniel Veillard48b2f892001-02-25 16:11:03 +00001145 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001146 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001147 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001148 xmlFreeDoc(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +00001149 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001150 endTimer("Freeing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001151 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001152}
1153
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001154/************************************************************************
1155 * *
1156 * Usage and Main *
1157 * *
1158 ************************************************************************/
1159
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00001160static void showVersion(const char *name) {
1161 fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
1162 fprintf(stderr, " compiled with: ");
1163#ifdef LIBXML_FTP_ENABLED
1164 fprintf(stderr, "FTP ");
1165#endif
1166#ifdef LIBXML_HTTP_ENABLED
1167 fprintf(stderr, "HTTP ");
1168#endif
1169#ifdef LIBXML_HTML_ENABLED
1170 fprintf(stderr, "HTML ");
1171#endif
1172#ifdef LIBXML_C14N_ENABLED
1173 fprintf(stderr, "C14N ");
1174#endif
1175#ifdef LIBXML_CATALOG_ENABLED
1176 fprintf(stderr, "Catalog ");
1177#endif
1178#ifdef LIBXML_DOCB_ENABLED
1179 fprintf(stderr, "DocBook ");
1180#endif
1181#ifdef LIBXML_XPATH_ENABLED
1182 fprintf(stderr, "XPath ");
1183#endif
1184#ifdef LIBXML_XPTR_ENABLED
1185 fprintf(stderr, "XPointer ");
1186#endif
1187#ifdef LIBXML_XINCLUDE_ENABLED
1188 fprintf(stderr, "XInclude ");
1189#endif
1190#ifdef LIBXML_ICONV_ENABLED
1191 fprintf(stderr, "Iconv ");
1192#endif
1193#ifdef DEBUG_MEMORY_LOCATION
1194 fprintf(stderr, "MemDebug ");
1195#endif
1196#ifdef LIBXML_UNICODE_ENABLED
1197 fprintf(stderr, "Unicode ");
1198#endif
1199#ifdef LIBXML_REGEXP_ENABLED
1200 fprintf(stderr, "Regexps ");
1201#endif
1202#ifdef LIBXML_AUTOMATA_ENABLED
1203 fprintf(stderr, "Automata ");
1204#endif
1205#ifdef LIBXML_SCHEMAS_ENABLED
1206 fprintf(stderr, "Schemas ");
1207#endif
1208 fprintf(stderr, "\n");
1209}
1210
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001211static void usage(const char *name) {
1212 printf("Usage : %s [options] XMLfiles ...\n", name);
1213 printf("\tParse the XML files and output the result of the parsing\n");
1214 printf("\t--version : display the version of the XML library used\n");
1215#ifdef LIBXML_DEBUG_ENABLED
1216 printf("\t--debug : dump a debug tree of the in-memory document\n");
1217 printf("\t--shell : run a navigating shell\n");
1218 printf("\t--debugent : debug the entities defined in the document\n");
Daniel Veillard8326e732003-01-07 00:19:07 +00001219#else
1220 printf("\t--debug : dump the nodes content when using --stream\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001221#endif
1222 printf("\t--copy : used to test the internal copy implementation\n");
1223 printf("\t--recover : output what was parsable on broken XML documents\n");
1224 printf("\t--noent : substitute entity references by their value\n");
1225 printf("\t--noout : don't output the result tree\n");
1226 printf("\t--htmlout : output results as HTML\n");
Daniel Veillard05c13a22001-09-09 08:38:09 +00001227 printf("\t--nowrap : do not put HTML doc wrapper\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001228 printf("\t--valid : validate the document in addition to std well-formed check\n");
1229 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
1230 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
1231 printf("\t--timing : print some timings\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001232 printf("\t--output file or -o file: save to a given file\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001233 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
1234 printf("\t--insert : ad-hoc test for valid insertions\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001235#ifdef HAVE_ZLIB_H
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001236 printf("\t--compress : turn on gzip compression of output\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001237#endif
Daniel Veillard89cad532001-10-22 09:46:13 +00001238#ifdef LIBXML_DOCB_ENABLED
1239 printf("\t--sgml : use the DocBook SGML parser\n");
1240#endif
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001241#ifdef LIBXML_HTML_ENABLED
1242 printf("\t--html : use the HTML parser\n");
1243#endif
1244 printf("\t--push : use the push mode of the parser\n");
1245#ifdef HAVE_SYS_MMAN_H
1246 printf("\t--memory : parse from memory\n");
1247#endif
1248 printf("\t--nowarning : do not emit warnings from parser/validator\n");
1249 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
Daniel Veillard90493a92001-08-14 14:12:47 +00001250 printf("\t--format : reformat/reindent the input\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001251 printf("\t--testIO : test user I/O support\n");
1252 printf("\t--encode encoding : output in the given encoding\n");
1253#ifdef LIBXML_CATALOG_ENABLED
Daniel Veillardbd9b0e82001-11-26 10:32:08 +00001254 printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
1255 printf("\t otherwise XML Catalogs starting from \n");
Daniel Veillard3be27512003-01-26 19:49:04 +00001256 printf("\t " XML_XML_DEFAULT_CATALOG " are activated by default\n");
Daniel Veillard05c13a22001-09-09 08:38:09 +00001257 printf("\t--nocatalogs: deactivate all catalogs\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001258#endif
1259 printf("\t--auto : generate a small doc on the fly\n");
1260#ifdef LIBXML_XINCLUDE_ENABLED
1261 printf("\t--xinclude : do XInclude processing\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001262#endif
Daniel Veillardcbaf3992001-12-31 16:16:02 +00001263 printf("\t--loaddtd : fetch external DTD\n");
Daniel Veillard48da9102001-08-07 01:10:10 +00001264 printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
Daniel Veillard29e43992001-12-13 22:21:58 +00001265 printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
Daniel Veillard7704fb12003-01-03 16:19:51 +00001266 printf("\t--stream : use the streaming interface to process very large files\n");
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001267 printf("\t--chkregister : verify the node registration code\n");
Daniel Veillardef4d3bc2003-02-07 12:38:22 +00001268#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard71531f32003-02-05 13:19:53 +00001269 printf("\t--relaxng schema : do RelaxNG validation against the schema\n");
1270#endif
Daniel Veillarda42f25f2002-01-25 14:15:40 +00001271 printf("\nLibxml project home page: http://xmlsoft.org/\n");
1272 printf("To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001273}
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001274
1275static void registerNode(xmlNodePtr node)
1276{
1277 node->_private = malloc(sizeof(long));
1278 *(long*)node->_private = (long) 0x81726354;
1279}
1280
1281static void deregisterNode(xmlNodePtr node)
1282{
1283 assert(node->_private != NULL);
1284 assert(*(long*)node->_private == (long) 0x81726354);
1285 free(node->_private);
1286}
1287
Daniel Veillard4a6845d2001-01-03 13:32:39 +00001288int
1289main(int argc, char **argv) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00001290 int i, acount;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001291 int files = 0;
Daniel Veillard845cce42002-01-09 11:51:37 +00001292 int version = 0;
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00001293 const char* indent;
1294
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001295 if (argc <= 1) {
1296 usage(argv[0]);
1297 return(1);
1298 }
Daniel Veillardbe803962000-06-28 23:40:59 +00001299 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001300 for (i = 1; i < argc ; i++) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001301 if (!strcmp(argv[i], "-"))
1302 break;
1303
1304 if (argv[i][0] != '-')
1305 continue;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001306 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
1307 debug++;
Daniel Veillard56ada1d2003-01-07 11:17:25 +00001308 else
1309#ifdef LIBXML_DEBUG_ENABLED
1310 if ((!strcmp(argv[i], "-shell")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001311 (!strcmp(argv[i], "--shell"))) {
1312 shell++;
1313 noout = 1;
1314 } else
1315#endif
1316 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
1317 copy++;
1318 else if ((!strcmp(argv[i], "-recover")) ||
1319 (!strcmp(argv[i], "--recover")))
1320 recovery++;
1321 else if ((!strcmp(argv[i], "-noent")) ||
1322 (!strcmp(argv[i], "--noent")))
1323 noent++;
Daniel Veillard4ec885a2001-06-17 10:31:07 +00001324 else if ((!strcmp(argv[i], "-version")) ||
Daniel Veillard845cce42002-01-09 11:51:37 +00001325 (!strcmp(argv[i], "--version"))) {
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00001326 showVersion(argv[0]);
Daniel Veillard845cce42002-01-09 11:51:37 +00001327 version = 1;
1328 } else if ((!strcmp(argv[i], "-noout")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001329 (!strcmp(argv[i], "--noout")))
1330 noout++;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001331 else if ((!strcmp(argv[i], "-o")) ||
1332 (!strcmp(argv[i], "-output")) ||
1333 (!strcmp(argv[i], "--output"))) {
1334 i++;
Daniel Veillard6e4f1c02002-04-09 09:55:20 +00001335 output = argv[i];
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001336 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001337 else if ((!strcmp(argv[i], "-htmlout")) ||
1338 (!strcmp(argv[i], "--htmlout")))
1339 htmlout++;
Daniel Veillard89cad532001-10-22 09:46:13 +00001340#ifdef LIBXML_DOCB_ENABLED
1341 else if ((!strcmp(argv[i], "-sgml")) ||
1342 (!strcmp(argv[i], "--sgml"))) {
1343 sgml++;
1344 }
1345#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001346#ifdef LIBXML_HTML_ENABLED
1347 else if ((!strcmp(argv[i], "-html")) ||
1348 (!strcmp(argv[i], "--html"))) {
1349 html++;
1350 }
1351#endif /* LIBXML_HTML_ENABLED */
1352 else if ((!strcmp(argv[i], "-nowrap")) ||
1353 (!strcmp(argv[i], "--nowrap")))
1354 nowrap++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001355 else if ((!strcmp(argv[i], "-loaddtd")) ||
1356 (!strcmp(argv[i], "--loaddtd")))
1357 loaddtd++;
Daniel Veillard48da9102001-08-07 01:10:10 +00001358 else if ((!strcmp(argv[i], "-dtdattr")) ||
1359 (!strcmp(argv[i], "--dtdattr"))) {
1360 loaddtd++;
1361 dtdattrs++;
1362 } else if ((!strcmp(argv[i], "-valid")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001363 (!strcmp(argv[i], "--valid")))
1364 valid++;
1365 else if ((!strcmp(argv[i], "-postvalid")) ||
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001366 (!strcmp(argv[i], "--postvalid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001367 postvalid++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001368 loaddtd++;
1369 } else if ((!strcmp(argv[i], "-dtdvalid")) ||
Daniel Veillardcd429612000-10-11 15:57:05 +00001370 (!strcmp(argv[i], "--dtdvalid"))) {
1371 i++;
1372 dtdvalid = argv[i];
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001373 loaddtd++;
Daniel Veillardcd429612000-10-11 15:57:05 +00001374 }
Daniel Veillard29e43992001-12-13 22:21:58 +00001375 else if ((!strcmp(argv[i], "-dropdtd")) ||
1376 (!strcmp(argv[i], "--dropdtd")))
1377 dropdtd++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001378 else if ((!strcmp(argv[i], "-insert")) ||
1379 (!strcmp(argv[i], "--insert")))
1380 insert++;
Daniel Veillard48b2f892001-02-25 16:11:03 +00001381 else if ((!strcmp(argv[i], "-timing")) ||
1382 (!strcmp(argv[i], "--timing")))
1383 timing++;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001384 else if ((!strcmp(argv[i], "-auto")) ||
1385 (!strcmp(argv[i], "--auto")))
1386 generate++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001387 else if ((!strcmp(argv[i], "-repeat")) ||
1388 (!strcmp(argv[i], "--repeat")))
1389 repeat++;
1390 else if ((!strcmp(argv[i], "-push")) ||
1391 (!strcmp(argv[i], "--push")))
1392 push++;
Daniel Veillard46e370e2000-07-21 20:32:03 +00001393#ifdef HAVE_SYS_MMAN_H
1394 else if ((!strcmp(argv[i], "-memory")) ||
1395 (!strcmp(argv[i], "--memory")))
1396 memory++;
1397#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +00001398 else if ((!strcmp(argv[i], "-testIO")) ||
1399 (!strcmp(argv[i], "--testIO")))
1400 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00001401#ifdef LIBXML_XINCLUDE_ENABLED
1402 else if ((!strcmp(argv[i], "-xinclude")) ||
1403 (!strcmp(argv[i], "--xinclude")))
1404 xinclude++;
1405#endif
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001406#ifdef HAVE_ZLIB_H
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001407 else if ((!strcmp(argv[i], "-compress")) ||
1408 (!strcmp(argv[i], "--compress"))) {
1409 compress++;
1410 xmlSetCompressMode(9);
1411 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001412#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001413 else if ((!strcmp(argv[i], "-nowarning")) ||
1414 (!strcmp(argv[i], "--nowarning"))) {
1415 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001416 xmlPedanticParserDefault(0);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001417 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001418 else if ((!strcmp(argv[i], "-pedantic")) ||
1419 (!strcmp(argv[i], "--pedantic"))) {
1420 xmlGetWarningsDefaultValue = 1;
1421 xmlPedanticParserDefault(1);
1422 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00001423#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001424 else if ((!strcmp(argv[i], "-debugent")) ||
1425 (!strcmp(argv[i], "--debugent"))) {
1426 debugent++;
1427 xmlParserDebugEntities = 1;
1428 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00001429#endif
Daniel Veillard81418e32001-05-22 15:08:55 +00001430#ifdef LIBXML_CATALOG_ENABLED
1431 else if ((!strcmp(argv[i], "-catalogs")) ||
1432 (!strcmp(argv[i], "--catalogs"))) {
Daniel Veillarde2940dd2001-08-22 00:06:49 +00001433 catalogs++;
1434 } else if ((!strcmp(argv[i], "-nocatalogs")) ||
1435 (!strcmp(argv[i], "--nocatalogs"))) {
1436 nocatalogs++;
Daniel Veillard81418e32001-05-22 15:08:55 +00001437 }
1438#endif
Daniel Veillardbe803962000-06-28 23:40:59 +00001439 else if ((!strcmp(argv[i], "-encode")) ||
1440 (!strcmp(argv[i], "--encode"))) {
1441 i++;
1442 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001443 /*
1444 * OK it's for testing purposes
1445 */
1446 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +00001447 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001448 else if ((!strcmp(argv[i], "-noblanks")) ||
1449 (!strcmp(argv[i], "--noblanks"))) {
1450 noblanks++;
1451 xmlKeepBlanksDefault(0);
Daniel Veillard90493a92001-08-14 14:12:47 +00001452 }
1453 else if ((!strcmp(argv[i], "-format")) ||
1454 (!strcmp(argv[i], "--format"))) {
1455 noblanks++;
1456 format++;
1457 xmlKeepBlanksDefault(0);
Daniel Veillard7704fb12003-01-03 16:19:51 +00001458 }
1459 else if ((!strcmp(argv[i], "-stream")) ||
1460 (!strcmp(argv[i], "--stream"))) {
1461 stream++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001462 }
1463 else if ((!strcmp(argv[i], "-chkregister")) ||
1464 (!strcmp(argv[i], "--chkregister"))) {
1465 chkregister++;
Daniel Veillard71531f32003-02-05 13:19:53 +00001466#ifdef LIBXML_SCHEMAS_ENABLED
1467 } else if ((!strcmp(argv[i], "-relaxng")) ||
1468 (!strcmp(argv[i], "--relaxng"))) {
1469 i++;
1470 relaxng = argv[i];
1471 noent++;
1472#endif
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001473 } else {
1474 fprintf(stderr, "Unknown option %s\n", argv[i]);
1475 usage(argv[0]);
1476 return(1);
1477 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001478 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00001479
1480#ifdef LIBXML_CATALOG_ENABLED
1481 if (nocatalogs == 0) {
1482 if (catalogs) {
1483 const char *catal;
1484
1485 catal = getenv("SGML_CATALOG_FILES");
Daniel Veillard6c5f9d12001-08-25 13:33:14 +00001486 if (catal != NULL) {
1487 xmlLoadCatalogs(catal);
1488 } else {
1489 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
1490 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00001491 }
1492 }
1493#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001494
1495 if (chkregister) {
1496 xmlRegisterNodeDefault(registerNode);
1497 xmlDeregisterNodeDefault(deregisterNode);
1498 }
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00001499
1500 indent = getenv("XMLLINT_INDENT");
1501 if(indent != NULL) {
1502 xmlTreeIndentString = indent;
1503 }
1504
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001505
Daniel Veillardd9bad132001-07-23 19:39:43 +00001506 xmlLineNumbersDefault(1);
Daniel Veillard48da9102001-08-07 01:10:10 +00001507 if (loaddtd != 0)
1508 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
1509 if (dtdattrs)
1510 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001511 if (noent != 0) xmlSubstituteEntitiesDefault(1);
1512 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
1513 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001514 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001515 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001516 xmlGenericError(xmlGenericErrorContext,
1517 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
1518 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001519 "<html><head><title>%s output</title></head>\n",
1520 argv[0]);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001521 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001522 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
1523 argv[0]);
1524 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001525
1526#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +00001527 if ((relaxng != NULL) && (stream == 0)) {
Daniel Veillard71531f32003-02-05 13:19:53 +00001528 xmlRelaxNGParserCtxtPtr ctxt;
1529
Daniel Veillardce192eb2003-04-16 15:58:05 +00001530 /* forces loading the DTDs */
1531 xmlLoadExtDtdDefaultValue |= 1;
Daniel Veillard42f12e92003-03-07 18:32:59 +00001532 if (timing) {
1533 startTimer();
1534 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001535 ctxt = xmlRelaxNGNewParserCtxt(relaxng);
1536 xmlRelaxNGSetParserErrors(ctxt,
1537 (xmlRelaxNGValidityErrorFunc) fprintf,
1538 (xmlRelaxNGValidityWarningFunc) fprintf,
1539 stderr);
1540 relaxngschemas = xmlRelaxNGParse(ctxt);
Daniel Veillardce192eb2003-04-16 15:58:05 +00001541 if (relaxngschemas == NULL) {
1542 xmlGenericError(xmlGenericErrorContext,
1543 "Relax-NG schema %s failed to compile\n", relaxng);
1544 relaxng = NULL;
1545 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001546 xmlRelaxNGFreeParserCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00001547 if (timing) {
1548 endTimer("Compiling the schemas");
1549 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001550 }
1551#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001552 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +00001553 if ((!strcmp(argv[i], "-encode")) ||
1554 (!strcmp(argv[i], "--encode"))) {
1555 i++;
1556 continue;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001557 } else if ((!strcmp(argv[i], "-o")) ||
1558 (!strcmp(argv[i], "-output")) ||
1559 (!strcmp(argv[i], "--output"))) {
1560 i++;
1561 continue;
Daniel Veillardbe803962000-06-28 23:40:59 +00001562 }
Daniel Veillardcd429612000-10-11 15:57:05 +00001563 if ((!strcmp(argv[i], "-dtdvalid")) ||
1564 (!strcmp(argv[i], "--dtdvalid"))) {
1565 i++;
1566 continue;
1567 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001568 if ((!strcmp(argv[i], "-relaxng")) ||
1569 (!strcmp(argv[i], "--relaxng"))) {
1570 i++;
1571 continue;
1572 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001573 if ((timing) && (repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00001574 startTimer();
Daniel Veillardcbaf3992001-12-31 16:16:02 +00001575 /* Remember file names. "-" means stdin. <sven@zen.org> */
Daniel Veillard4a6845d2001-01-03 13:32:39 +00001576 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001577 if (repeat) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00001578 for (acount = 0;acount < 100 * repeat;acount++)
1579 if (stream != 0)
1580 streamFile(argv[i]);
1581 else
1582 parseAndPrintFile(argv[i]);
1583 } else {
1584 if (stream != 0)
1585 streamFile(argv[i]);
1586 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001587 parseAndPrintFile(argv[i]);
Daniel Veillard7704fb12003-01-03 16:19:51 +00001588 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001589 files ++;
Daniel Veillarda7866932001-12-04 13:14:44 +00001590 if ((timing) && (repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001591 endTimer("100 iterations");
Daniel Veillarda7866932001-12-04 13:14:44 +00001592 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001593 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001594 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001595 if (generate)
1596 parseAndPrintFile(NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001597 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001598 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001599 }
Daniel Veillard845cce42002-01-09 11:51:37 +00001600 if ((files == 0) && (!generate) && (version == 0)) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001601 usage(argv[0]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001602 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001603#ifdef LIBXML_SCHEMAS_ENABLED
1604 if (relaxngschemas != NULL)
1605 xmlRelaxNGFree(relaxngschemas);
1606 xmlRelaxNGCleanupTypes();
1607#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001608 xmlCleanupParser();
1609 xmlMemoryDump();
1610
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001611 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001612}
Daniel Veillard88a172f2000-08-04 18:23:10 +00001613