blob: df5e51fa51f80a2cc8f1dea1ebfc2c34023130b2 [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>
Daniel Veillard75bb3bb2003-05-12 15:25:56 +000089#include <libxml/xmlschemas.h>
Daniel Veillard71531f32003-02-05 13:19:53 +000090#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000091
Daniel Veillard3be27512003-01-26 19:49:04 +000092#ifndef XML_XML_DEFAULT_CATALOG
93#define XML_XML_DEFAULT_CATALOG "file:///etc/xml/catalog"
94#endif
95
Daniel Veillardce8b83b2000-04-05 18:38:42 +000096#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +000097static int shell = 0;
98static int debugent = 0;
99#endif
Daniel Veillard8326e732003-01-07 00:19:07 +0000100static int debug = 0;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000101static int copy = 0;
102static int recovery = 0;
103static int noent = 0;
104static int noout = 0;
105static int nowrap = 0;
106static int valid = 0;
107static int postvalid = 0;
Daniel Veillardcd429612000-10-11 15:57:05 +0000108static char * dtdvalid = NULL;
Daniel Veillard71531f32003-02-05 13:19:53 +0000109#ifdef LIBXML_SCHEMAS_ENABLED
110static char * relaxng = NULL;
111static xmlRelaxNGPtr relaxngschemas = NULL;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +0000112static char * schema = NULL;
113static xmlSchemaPtr wxschemas = NULL;
Daniel Veillard71531f32003-02-05 13:19:53 +0000114#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000115static int repeat = 0;
116static int insert = 0;
117static int compress = 0;
Daniel Veillard89cad532001-10-22 09:46:13 +0000118#ifdef LIBXML_DOCB_ENABLED
119static int sgml = 0;
120#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000121static int html = 0;
122static int htmlout = 0;
123static int push = 0;
Daniel Veillard46e370e2000-07-21 20:32:03 +0000124#ifdef HAVE_SYS_MMAN_H
125static int memory = 0;
126#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000127static int noblanks = 0;
Daniel Veillard90493a92001-08-14 14:12:47 +0000128static int format = 0;
Daniel Veillard5e873c42000-04-12 13:27:38 +0000129static int testIO = 0;
Daniel Veillardbe803962000-06-28 23:40:59 +0000130static char *encoding = NULL;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000131#ifdef LIBXML_XINCLUDE_ENABLED
132static int xinclude = 0;
133#endif
Daniel Veillard48da9102001-08-07 01:10:10 +0000134static int dtdattrs = 0;
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000135static int loaddtd = 0;
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000136static int progresult = 0;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000137static int timing = 0;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000138static int generate = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000139static int dropdtd = 0;
Daniel Veillarde2940dd2001-08-22 00:06:49 +0000140#ifdef LIBXML_CATALOG_ENABLED
141static int catalogs = 0;
142static int nocatalogs = 0;
143#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +0000144static int stream = 0;
Daniel Veillard8a1b1852003-01-05 22:37:17 +0000145static int chkregister = 0;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +0000146static const char *output = NULL;
147
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000148
Daniel Veillard01db67c2001-12-18 07:09:59 +0000149/*
150 * Internal timing routines to remove the necessity to have unix-specific
151 * function calls
152 */
153
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000154#ifndef HAVE_GETTIMEOFDAY
155#ifdef HAVE_SYS_TIMEB_H
156#ifdef HAVE_SYS_TIME_H
157#ifdef HAVE_FTIME
158
Daniel Veillard01c13b52002-12-10 15:19:08 +0000159static int
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000160my_gettimeofday(struct timeval *tvp, void *tzp)
161{
162 struct timeb timebuffer;
163
164 ftime(&timebuffer);
165 if (tvp) {
166 tvp->tv_sec = timebuffer.time;
167 tvp->tv_usec = timebuffer.millitm * 1000L;
168 }
169 return (0);
170}
171#define HAVE_GETTIMEOFDAY 1
172#define gettimeofday my_gettimeofday
173
174#endif /* HAVE_FTIME */
175#endif /* HAVE_SYS_TIME_H */
176#endif /* HAVE_SYS_TIMEB_H */
177#endif /* !HAVE_GETTIMEOFDAY */
178
Daniel Veillard01db67c2001-12-18 07:09:59 +0000179#if defined(HAVE_GETTIMEOFDAY)
180static struct timeval begin, end;
181
182/*
183 * startTimer: call where you want to start timing
184 */
185static void
186startTimer(void)
187{
188 gettimeofday(&begin, NULL);
189}
190
191/*
192 * endTimer: call where you want to stop timing and to print out a
193 * message about the timing performed; format is a printf
194 * type argument
195 */
196static void
Daniel Veillard118aed72002-09-24 14:13:13 +0000197endTimer(const char *fmt, ...)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000198{
199 long msec;
200 va_list ap;
201
202 gettimeofday(&end, NULL);
203 msec = end.tv_sec - begin.tv_sec;
204 msec *= 1000;
205 msec += (end.tv_usec - begin.tv_usec) / 1000;
206
207#ifndef HAVE_STDARG_H
208#error "endTimer required stdarg functions"
209#endif
Daniel Veillard118aed72002-09-24 14:13:13 +0000210 va_start(ap, fmt);
211 vfprintf(stderr, fmt, ap);
Daniel Veillard01db67c2001-12-18 07:09:59 +0000212 va_end(ap);
213
214 fprintf(stderr, " took %ld ms\n", msec);
215}
216#elif defined(HAVE_TIME_H)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000217/*
218 * No gettimeofday function, so we have to make do with calling clock.
219 * This is obviously less accurate, but there's little we can do about
220 * that.
221 */
Daniel Veillard90bc3712002-03-07 15:12:58 +0000222#ifndef CLOCKS_PER_SEC
223#define CLOCKS_PER_SEC 100
224#endif
Daniel Veillard01db67c2001-12-18 07:09:59 +0000225
226static clock_t begin, end;
227static void
228startTimer(void)
229{
230 begin = clock();
231}
232static void
233endTimer(const char *fmt, ...)
234{
235 long msec;
236 va_list ap;
237
238 end = clock();
239 msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
240
241#ifndef HAVE_STDARG_H
242#error "endTimer required stdarg functions"
243#endif
244 va_start(ap, fmt);
245 vfprintf(stderr, fmt, ap);
246 va_end(ap);
247 fprintf(stderr, " took %ld ms\n", msec);
248}
249#else
250
251/*
252 * We don't have a gettimeofday or time.h, so we just don't do timing
253 */
254static void
255startTimer(void)
256{
257 /*
258 * Do nothing
259 */
260}
261static void
262endTimer(char *format, ...)
263{
264 /*
265 * We cannot do anything because we don't have a timing function
266 */
267#ifdef HAVE_STDARG_H
268 va_start(ap, format);
269 vfprintf(stderr, format, ap);
270 va_end(ap);
271 fprintf(stderr, " was not timed\n", msec);
272#else
273 /* We don't have gettimeofday, time or stdarg.h, what crazy world is
274 * this ?!
275 */
276#endif
277}
278#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000279/************************************************************************
280 * *
281 * HTML ouput *
282 * *
283 ************************************************************************/
284char buffer[50000];
285
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000286static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000287xmlHTMLEncodeSend(void) {
288 char *result;
289
290 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
291 if (result) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000292 xmlGenericError(xmlGenericErrorContext, "%s", result);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000293 xmlFree(result);
294 }
295 buffer[0] = 0;
296}
297
298/**
299 * xmlHTMLPrintFileInfo:
300 * @input: an xmlParserInputPtr input
301 *
302 * Displays the associated file and line informations for the current input
303 */
304
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000305static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000306xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000307 int len;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000308 xmlGenericError(xmlGenericErrorContext, "<p>");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000309
310 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000311 if (input != NULL) {
312 if (input->filename) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000313 snprintf(&buffer[len], sizeof(buffer) - len, "%s:%d: ", input->filename,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000314 input->line);
315 } else {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000316 snprintf(&buffer[len], sizeof(buffer) - len, "Entity: line %d: ", input->line);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000317 }
318 }
319 xmlHTMLEncodeSend();
320}
321
322/**
323 * xmlHTMLPrintFileContext:
324 * @input: an xmlParserInputPtr input
325 *
326 * Displays current context within the input content for error tracking
327 */
328
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000329static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000330xmlHTMLPrintFileContext(xmlParserInputPtr input) {
331 const xmlChar *cur, *base;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000332 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000333 int n;
334
335 if (input == NULL) return;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000336 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000337 cur = input->cur;
338 base = input->base;
339 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
340 cur--;
341 }
342 n = 0;
343 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
344 cur--;
345 if ((*cur == '\n') || (*cur == '\r')) cur++;
346 base = cur;
347 n = 0;
348 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000349 len = strlen(buffer);
350 snprintf(&buffer[len], sizeof(buffer) - len, "%c",
351 (unsigned char) *cur++);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000352 n++;
353 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000354 len = strlen(buffer);
355 snprintf(&buffer[len], sizeof(buffer) - len, "\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000356 cur = input->cur;
357 while ((*cur == '\n') || (*cur == '\r'))
358 cur--;
359 n = 0;
360 while ((cur != base) && (n++ < 80)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000361 len = strlen(buffer);
362 snprintf(&buffer[len], sizeof(buffer) - len, " ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000363 base++;
364 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000365 len = strlen(buffer);
366 snprintf(&buffer[len], sizeof(buffer) - len, "^\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000367 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000368 xmlGenericError(xmlGenericErrorContext, "</pre>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000369}
370
371/**
372 * xmlHTMLError:
373 * @ctx: an XML parser context
374 * @msg: the message to display/transmit
375 * @...: extra parameters for the message display
376 *
377 * Display and format an error messages, gives file, line, position and
378 * extra parameters.
379 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000380static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000381xmlHTMLError(void *ctx, const char *msg, ...)
382{
383 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
384 xmlParserInputPtr input;
385 xmlParserInputPtr cur = NULL;
386 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000387 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000388
389 buffer[0] = 0;
390 input = ctxt->input;
391 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
392 cur = input;
393 input = ctxt->inputTab[ctxt->inputNr - 2];
394 }
395
396 xmlHTMLPrintFileInfo(input);
397
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000398 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000399 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000400 len = strlen(buffer);
401 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000402 va_end(args);
403 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000404 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000405
406 xmlHTMLPrintFileContext(input);
407 xmlHTMLEncodeSend();
408}
409
410/**
411 * xmlHTMLWarning:
412 * @ctx: an XML parser context
413 * @msg: the message to display/transmit
414 * @...: extra parameters for the message display
415 *
416 * Display and format a warning messages, gives file, line, position and
417 * extra parameters.
418 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000419static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000420xmlHTMLWarning(void *ctx, const char *msg, ...)
421{
422 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
423 xmlParserInputPtr input;
424 xmlParserInputPtr cur = NULL;
425 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000426 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000427
428 buffer[0] = 0;
429 input = ctxt->input;
430 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
431 cur = input;
432 input = ctxt->inputTab[ctxt->inputNr - 2];
433 }
434
435
436 xmlHTMLPrintFileInfo(input);
437
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000438 xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000439 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000440 len = strlen(buffer);
441 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000442 va_end(args);
443 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000444 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000445
446 xmlHTMLPrintFileContext(input);
447 xmlHTMLEncodeSend();
448}
449
450/**
451 * xmlHTMLValidityError:
452 * @ctx: an XML parser context
453 * @msg: the message to display/transmit
454 * @...: extra parameters for the message display
455 *
456 * Display and format an validity error messages, gives file,
457 * line, position and extra parameters.
458 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000459static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000460xmlHTMLValidityError(void *ctx, const char *msg, ...)
461{
462 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
463 xmlParserInputPtr input;
464 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000465 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000466
467 buffer[0] = 0;
468 input = ctxt->input;
469 if ((input->filename == NULL) && (ctxt->inputNr > 1))
470 input = ctxt->inputTab[ctxt->inputNr - 2];
471
472 xmlHTMLPrintFileInfo(input);
473
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000474 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000475 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000476 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000477 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000478 va_end(args);
479 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000480 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000481
482 xmlHTMLPrintFileContext(input);
483 xmlHTMLEncodeSend();
484}
485
486/**
487 * xmlHTMLValidityWarning:
488 * @ctx: an XML parser context
489 * @msg: the message to display/transmit
490 * @...: extra parameters for the message display
491 *
492 * Display and format a validity warning messages, gives file, line,
493 * position and extra parameters.
494 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000495static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000496xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
497{
498 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
499 xmlParserInputPtr input;
500 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000501 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000502
503 buffer[0] = 0;
504 input = ctxt->input;
505 if ((input->filename == NULL) && (ctxt->inputNr > 1))
506 input = ctxt->inputTab[ctxt->inputNr - 2];
507
508 xmlHTMLPrintFileInfo(input);
509
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000510 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000511 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000512 len = strlen(buffer);
513 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000514 va_end(args);
515 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000516 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000517
518 xmlHTMLPrintFileContext(input);
519 xmlHTMLEncodeSend();
520}
521
522/************************************************************************
523 * *
524 * Shell Interface *
525 * *
526 ************************************************************************/
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000527#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000528/**
529 * xmlShellReadline:
530 * @prompt: the prompt value
531 *
532 * Read a string
533 *
534 * Returns a pointer to it or NULL on EOF the caller is expected to
535 * free the returned string.
536 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000537static char *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000538xmlShellReadline(char *prompt) {
539#ifdef HAVE_LIBREADLINE
540 char *line_read;
541
542 /* Get a line from the user. */
543 line_read = readline (prompt);
544
545 /* If the line has any text in it, save it on the history. */
546 if (line_read && *line_read)
547 add_history (line_read);
548
549 return (line_read);
550#else
551 char line_read[501];
Daniel Veillard29e43992001-12-13 22:21:58 +0000552 char *ret;
553 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000554
555 if (prompt != NULL)
556 fprintf(stdout, "%s", prompt);
557 if (!fgets(line_read, 500, stdin))
558 return(NULL);
559 line_read[500] = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000560 len = strlen(line_read);
561 ret = (char *) malloc(len + 1);
562 if (ret != NULL) {
563 memcpy (ret, line_read, len + 1);
564 }
565 return(ret);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000566#endif
567}
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000568#endif /* LIBXML_DEBUG_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000569
570/************************************************************************
571 * *
Daniel Veillard5e873c42000-04-12 13:27:38 +0000572 * I/O Interfaces *
573 * *
574 ************************************************************************/
575
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000576static int myRead(FILE *f, char * buf, int len) {
577 return(fread(buf, 1, len, f));
Daniel Veillard5e873c42000-04-12 13:27:38 +0000578}
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000579static void myClose(FILE *f) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000580 if (f != stdin) {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000581 fclose(f);
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000582 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000583}
584
585/************************************************************************
586 * *
Daniel Veillard7704fb12003-01-03 16:19:51 +0000587 * Stream Test processing *
588 * *
589 ************************************************************************/
590static int count = 0;
591static int elem, attrs;
592
593static void processNode(xmlTextReaderPtr reader) {
Daniel Veillarde59494f2003-01-04 16:35:29 +0000594 xmlChar *name, *value;
Daniel Veillard7704fb12003-01-03 16:19:51 +0000595
Daniel Veillarde59494f2003-01-04 16:35:29 +0000596 name = xmlTextReaderName(reader);
597 if (name == NULL)
598 name = xmlStrdup(BAD_CAST "--");
Daniel Veillard99737f52003-03-22 14:55:50 +0000599
Daniel Veillarde59494f2003-01-04 16:35:29 +0000600 value = xmlTextReaderValue(reader);
Daniel Veillard7704fb12003-01-03 16:19:51 +0000601
Daniel Veillard99737f52003-03-22 14:55:50 +0000602 printf("%d %d %s %d %d",
Daniel Veillarde59494f2003-01-04 16:35:29 +0000603 xmlTextReaderDepth(reader),
604 xmlTextReaderNodeType(reader),
605 name,
Daniel Veillard99737f52003-03-22 14:55:50 +0000606 xmlTextReaderIsEmptyElement(reader),
607 xmlTextReaderHasValue(reader));
Daniel Veillarde59494f2003-01-04 16:35:29 +0000608 xmlFree(name);
609 if (value == NULL)
610 printf("\n");
611 else {
612 printf(" %s\n", value);
613 xmlFree(value);
Daniel Veillard7704fb12003-01-03 16:19:51 +0000614 }
615}
616
617static void streamFile(char *filename) {
618 xmlTextReaderPtr reader;
619 int ret;
620
621 if (count) {
622 elem = 0;
623 attrs = 0;
624 }
625
626 reader = xmlNewTextReaderFilename(filename);
627 if (reader != NULL) {
628 if (valid)
629 xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
Daniel Veillardce192eb2003-04-16 15:58:05 +0000630 else
631 xmlTextReaderSetParserProp(reader, XML_PARSER_LOADDTD, 1);
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000632#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +0000633 if (relaxng != NULL) {
634 if (timing) {
635 startTimer();
636 }
637 ret = xmlTextReaderRelaxNGValidate(reader, relaxng);
638 if (ret < 0) {
639 xmlGenericError(xmlGenericErrorContext,
640 "Relax-NG schema %s failed to compile\n", relaxng);
641 relaxng = NULL;
642 }
643 if (timing) {
644 endTimer("Compiling the schemas");
645 }
646 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000647#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +0000648
649 /*
650 * Process all nodes in sequence
651 */
Daniel Veillardce192eb2003-04-16 15:58:05 +0000652 if (timing) {
653 startTimer();
654 }
Daniel Veillard7704fb12003-01-03 16:19:51 +0000655 ret = xmlTextReaderRead(reader);
656 while (ret == 1) {
657 if (debug)
658 processNode(reader);
659 ret = xmlTextReaderRead(reader);
660 }
Daniel Veillardce192eb2003-04-16 15:58:05 +0000661 if (timing) {
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000662#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +0000663 if ((valid) || (relaxng != NULL))
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000664#else
665 if (valid)
666#endif
Daniel Veillardce192eb2003-04-16 15:58:05 +0000667 endTimer("Parsing and validating");
668 else
669 endTimer("Parsing");
670 }
Daniel Veillard7704fb12003-01-03 16:19:51 +0000671
Daniel Veillardf6bad792003-04-11 19:38:54 +0000672 if (valid) {
673 if (xmlTextReaderIsValid(reader) != 1) {
674 xmlGenericError(xmlGenericErrorContext,
675 "Document %s does not validate\n", filename);
676 progresult = 3;
677 }
678 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000679#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf4e55762003-04-15 23:32:22 +0000680 if (relaxng != NULL) {
681 if (xmlTextReaderIsValid(reader) != 1) {
682 printf("%s fails to validate\n", filename);
683 progresult = 3;
684 } else {
685 printf("%s validates\n", filename);
686 }
687 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000688#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +0000689 /*
690 * Done, cleanup and status
691 */
692 xmlFreeTextReader(reader);
693 if (ret != 0) {
694 printf("%s : failed to parse\n", filename);
Daniel Veillardf6bad792003-04-11 19:38:54 +0000695 progresult = 1;
Daniel Veillard7704fb12003-01-03 16:19:51 +0000696 }
697 } else {
698 fprintf(stderr, "Unable to open %s\n", filename);
Daniel Veillardf6bad792003-04-11 19:38:54 +0000699 progresult = 1;
Daniel Veillard7704fb12003-01-03 16:19:51 +0000700 }
701}
702
703/************************************************************************
704 * *
705 * Tree Test processing *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000706 * *
707 ************************************************************************/
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000708static void parseAndPrintFile(char *filename) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000709 xmlDocPtr doc = NULL, tmp;
710
Daniel Veillard48b2f892001-02-25 16:11:03 +0000711 if ((timing) && (!repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +0000712 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +0000713
714
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000715 if (filename == NULL) {
716 if (generate) {
717 xmlNodePtr n;
718
719 doc = xmlNewDoc(BAD_CAST "1.0");
720 n = xmlNewNode(NULL, BAD_CAST "info");
721 xmlNodeSetContent(n, BAD_CAST "abc");
722 xmlDocSetRootElement(doc, n);
723 }
724 }
Daniel Veillard89cad532001-10-22 09:46:13 +0000725#ifdef LIBXML_DOCB_ENABLED
726 /*
727 * build an SGML tree from a string;
728 */
729 else if ((sgml) && (push)) {
730 FILE *f;
731
732 f = fopen(filename, "r");
733 if (f != NULL) {
734 int res, size = 3;
735 char chars[4096];
736 docbParserCtxtPtr ctxt;
737
738 /* if (repeat) */
739 size = 4096;
740 res = fread(chars, 1, 4, f);
741 if (res > 0) {
742 ctxt = docbCreatePushParserCtxt(NULL, NULL,
743 chars, res, filename, 0);
744 while ((res = fread(chars, 1, size, f)) > 0) {
745 docbParseChunk(ctxt, chars, res, 0);
746 }
747 docbParseChunk(ctxt, chars, 0, 1);
748 doc = ctxt->myDoc;
749 docbFreeParserCtxt(ctxt);
750 }
751 fclose(f);
752 }
753 } else if (sgml) {
754 doc = docbParseFile(filename, NULL);
755 }
756#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000757#ifdef LIBXML_HTML_ENABLED
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000758 else if (html) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000759 doc = htmlParseFile(filename, NULL);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000760 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000761#endif /* LIBXML_HTML_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000762 else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000763 /*
764 * build an XML tree from a string;
765 */
766 if (push) {
767 FILE *f;
768
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000769 /* '-' Usually means stdin -<sven@zen.org> */
770 if ((filename[0] == '-') && (filename[1] == 0)) {
771 f = stdin;
772 } else {
773 f = fopen(filename, "r");
774 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000775 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +0000776 int ret;
Daniel Veillarda880b122003-04-21 21:36:41 +0000777 int res, size = 1024;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000778 char chars[1024];
779 xmlParserCtxtPtr ctxt;
780
Daniel Veillarda880b122003-04-21 21:36:41 +0000781 /* if (repeat) size = 1024; */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000782 res = fread(chars, 1, 4, f);
783 if (res > 0) {
784 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
785 chars, res, filename);
786 while ((res = fread(chars, 1, size, f)) > 0) {
787 xmlParseChunk(ctxt, chars, res, 0);
788 }
789 xmlParseChunk(ctxt, chars, 0, 1);
790 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +0000791 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000792 xmlFreeParserCtxt(ctxt);
Daniel Veillarde715dd22000-08-29 18:29:38 +0000793 if (!ret) {
794 xmlFreeDoc(doc);
795 doc = NULL;
796 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000797 }
798 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000799 } else if (testIO) {
800 int ret;
801 FILE *f;
802
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000803 /* '-' Usually means stdin -<sven@zen.org> */
804 if ((filename[0] == '-') && (filename[1] == 0)) {
805 f = stdin;
806 } else {
807 f = fopen(filename, "r");
808 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000809 if (f != NULL) {
810 xmlParserCtxtPtr ctxt;
811
812 ctxt = xmlCreateIOParserCtxt(NULL, NULL,
813 (xmlInputReadCallback) myRead,
814 (xmlInputCloseCallback) myClose,
815 f, XML_CHAR_ENCODING_NONE);
816 xmlParseDocument(ctxt);
817
818 ret = ctxt->wellFormed;
819 doc = ctxt->myDoc;
820 xmlFreeParserCtxt(ctxt);
821 if (!ret) {
822 xmlFreeDoc(doc);
823 doc = NULL;
824 }
825 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000826 } else if (recovery) {
827 doc = xmlRecoverFile(filename);
828 } else if (htmlout) {
829 int ret;
830 xmlParserCtxtPtr ctxt;
831 xmlSAXHandler silent, *old;
832
833 ctxt = xmlCreateFileParserCtxt(filename);
Daniel Veillard88a172f2000-08-04 18:23:10 +0000834
835 if (ctxt == NULL) {
Daniel Veillardcbaf3992001-12-31 16:16:02 +0000836 /* If xmlCreateFileParserCtxt() return NULL something
Daniel Veillard88a172f2000-08-04 18:23:10 +0000837 strange happened so we don't want to do anything. Do
838 we want to print an error message here?
839 <sven@zen.org> */
Daniel Veillard7ebb1ee2000-08-04 18:24:45 +0000840 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000841 } else {
842 memcpy(&silent, ctxt->sax, sizeof(silent));
843 old = ctxt->sax;
844 silent.error = xmlHTMLError;
845 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000846 silent.warning = xmlHTMLWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000847 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000848 silent.warning = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000849 silent.fatalError = xmlHTMLError;
850 ctxt->sax = &silent;
851 ctxt->vctxt.error = xmlHTMLValidityError;
852 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000853 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000854 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000855 ctxt->vctxt.warning = NULL;
856
Daniel Veillard88a172f2000-08-04 18:23:10 +0000857 xmlParseDocument(ctxt);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000858
Daniel Veillard88a172f2000-08-04 18:23:10 +0000859 ret = ctxt->wellFormed;
860 doc = ctxt->myDoc;
861 ctxt->sax = old;
862 xmlFreeParserCtxt(ctxt);
863 if (!ret) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000864 xmlFreeDoc(doc);
865 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000866 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000867 }
Daniel Veillard46e370e2000-07-21 20:32:03 +0000868#ifdef HAVE_SYS_MMAN_H
869 } else if (memory) {
870 int fd;
871 struct stat info;
872 const char *base;
873 if (stat(filename, &info) < 0)
874 return;
875 if ((fd = open(filename, O_RDONLY)) < 0)
876 return;
877 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillard29579362000-08-14 17:57:48 +0000878 if (base == (void *) MAP_FAILED)
Daniel Veillard46e370e2000-07-21 20:32:03 +0000879 return;
880
881 doc = xmlParseMemory((char *) base, info.st_size);
882 munmap((char *) base, info.st_size);
883#endif
Daniel Veillardea7751d2002-12-20 00:16:24 +0000884 } else if (valid) {
885 int ret;
886 xmlParserCtxtPtr ctxt;
887
888 ctxt = xmlCreateFileParserCtxt(filename);
889
890 if (ctxt == NULL) {
891 doc = NULL;
892 } else {
893 xmlParseDocument(ctxt);
894 if (ctxt->valid == 0)
895 progresult = 4;
896 ret = ctxt->wellFormed;
897 doc = ctxt->myDoc;
898 xmlFreeParserCtxt(ctxt);
899 if (!ret) {
900 xmlFreeDoc(doc);
901 doc = NULL;
902 }
903 }
904 } else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000905 doc = xmlParseFile(filename);
Daniel Veillardea7751d2002-12-20 00:16:24 +0000906 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000907 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000908
Daniel Veillard88a172f2000-08-04 18:23:10 +0000909 /*
910 * If we don't have a document we might as well give up. Do we
911 * want an error message here? <sven@zen.org> */
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000912 if (doc == NULL) {
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000913 progresult = 1;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000914 return;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000915 }
916
Daniel Veillard48b2f892001-02-25 16:11:03 +0000917 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +0000918 endTimer("Parsing");
Daniel Veillard48b2f892001-02-25 16:11:03 +0000919 }
920
Daniel Veillard29e43992001-12-13 22:21:58 +0000921 /*
922 * Remove DOCTYPE nodes
923 */
924 if (dropdtd) {
925 xmlDtdPtr dtd;
926
927 dtd = xmlGetIntSubset(doc);
928 if (dtd != NULL) {
929 xmlUnlinkNode((xmlNodePtr)dtd);
930 xmlFreeDtd(dtd);
931 }
932 }
933
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000934#ifdef LIBXML_XINCLUDE_ENABLED
Daniel Veillard48b2f892001-02-25 16:11:03 +0000935 if (xinclude) {
936 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +0000937 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +0000938 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000939 xmlXIncludeProcess(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000940 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +0000941 endTimer("Xinclude processing");
Daniel Veillard48b2f892001-02-25 16:11:03 +0000942 }
943 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000944#endif
Daniel Veillard88a172f2000-08-04 18:23:10 +0000945
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000946#ifdef LIBXML_DEBUG_ENABLED
947 /*
Daniel Veillardcbaf3992001-12-31 16:16:02 +0000948 * shell interaction
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000949 */
950 if (shell)
951 xmlShell(doc, filename, xmlShellReadline, stdout);
952#endif
953
954 /*
955 * test intermediate copy if needed.
956 */
957 if (copy) {
958 tmp = doc;
959 doc = xmlCopyDoc(doc, 1);
960 xmlFreeDoc(tmp);
961 }
962
963 if ((insert) && (!html)) {
964 const xmlChar* list[256];
965 int nb, i;
966 xmlNodePtr node;
967
968 if (doc->children != NULL) {
969 node = doc->children;
970 while ((node != NULL) && (node->last == NULL)) node = node->next;
971 if (node != NULL) {
972 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
973 if (nb < 0) {
974 printf("could not get valid list of elements\n");
975 } else if (nb == 0) {
MDT 2001 John Fleckbbb9e432001-09-24 03:08:43 +0000976 printf("No element can be inserted under root\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000977 } else {
MDT 2001 John Fleckbbb9e432001-09-24 03:08:43 +0000978 printf("%d element types can be inserted under root:\n",
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000979 nb);
980 for (i = 0;i < nb;i++) {
Daniel Veillard8a1b1852003-01-05 22:37:17 +0000981 printf("%s\n", (char *) list[i]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000982 }
983 }
984 }
985 }
986 }else if (noout == 0) {
987 /*
988 * print it.
989 */
990#ifdef LIBXML_DEBUG_ENABLED
991 if (!debug) {
992#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +0000993 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +0000994 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +0000995 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +0000996#ifdef HAVE_SYS_MMAN_H
Daniel Veillarda6d8eb62000-12-27 10:46:47 +0000997 if (memory) {
998 xmlChar *result;
999 int len;
1000
1001 if (encoding != NULL) {
Daniel Veillardd536f702001-11-08 17:32:47 +00001002 if ( format ) {
1003 xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
1004 } else {
1005 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
1006 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001007 } else {
Daniel Veillard90493a92001-08-14 14:12:47 +00001008 if (format)
1009 xmlDocDumpFormatMemory(doc, &result, &len, 1);
1010 else
1011 xmlDocDumpMemory(doc, &result, &len);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001012 }
1013 if (result == NULL) {
1014 fprintf(stderr, "Failed to save\n");
1015 } else {
1016 write(1, result, len);
1017 xmlFree(result);
1018 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +00001019 } else
1020#endif /* HAVE_SYS_MMAN_H */
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001021 if (compress) {
1022 xmlSaveFile(output ? output : "-", doc);
1023 }
Daniel Veillardd536f702001-11-08 17:32:47 +00001024 else if (encoding != NULL) {
1025 if ( format ) {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001026 xmlSaveFormatFileEnc(output ? output : "-", doc, encoding, 1);
1027 }
Daniel Veillardd536f702001-11-08 17:32:47 +00001028 else {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001029 xmlSaveFileEnc(output ? output : "-", doc, encoding);
Daniel Veillardd536f702001-11-08 17:32:47 +00001030 }
1031 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001032 else if (format) {
1033 xmlSaveFormatFile(output ? output : "-", doc, 1);
1034 }
1035 else {
1036 FILE *out;
1037 if (output == NULL)
1038 out = stdout;
1039 else {
1040 out = fopen(output,"wb");
1041 }
1042 xmlDocDump(out, doc);
1043
1044 if (output)
1045 fclose(out);
1046 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001047 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001048 endTimer("Saving");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001049 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001050#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001051 } else {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001052 FILE *out;
1053 if (output == NULL)
1054 out = stdout;
1055 else {
1056 out = fopen(output,"wb");
1057 }
1058 xmlDebugDumpDocument(out, doc);
1059
1060 if (output)
1061 fclose(out);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001062 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001063#endif
1064 }
1065
1066 /*
1067 * A posteriori validation test
1068 */
Daniel Veillardcd429612000-10-11 15:57:05 +00001069 if (dtdvalid != NULL) {
1070 xmlDtdPtr dtd;
1071
Daniel Veillard48b2f892001-02-25 16:11:03 +00001072 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001073 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001074 }
Daniel Veillardcd429612000-10-11 15:57:05 +00001075 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
Daniel Veillard48b2f892001-02-25 16:11:03 +00001076 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001077 endTimer("Parsing DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001078 }
Daniel Veillardcd429612000-10-11 15:57:05 +00001079 if (dtd == NULL) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001080 xmlGenericError(xmlGenericErrorContext,
1081 "Could not parse DTD %s\n", dtdvalid);
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001082 progresult = 2;
Daniel Veillardcd429612000-10-11 15:57:05 +00001083 } else {
Daniel Veillarda37aab82003-06-09 09:10:36 +00001084 xmlValidCtxtPtr cvp;
1085
1086 if ((cvp = xmlNewValidCtxt()) == NULL) {
1087 xmlGenericError(xmlGenericErrorContext,
1088 "Couldn't allocate validation context\n");
1089 exit(-1);
1090 }
1091 cvp->userData = (void *) stderr;
1092 cvp->error = (xmlValidityErrorFunc) fprintf;
1093 cvp->warning = (xmlValidityWarningFunc) fprintf;
1094
Daniel Veillard48b2f892001-02-25 16:11:03 +00001095 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001096 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001097 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00001098 if (!xmlValidateDtd(cvp, doc, dtd)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001099 xmlGenericError(xmlGenericErrorContext,
1100 "Document %s does not validate against %s\n",
Daniel Veillardcd429612000-10-11 15:57:05 +00001101 filename, dtdvalid);
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 against DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001106 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00001107 xmlFreeValidCtxt(cvp);
Daniel Veillardcd429612000-10-11 15:57:05 +00001108 xmlFreeDtd(dtd);
1109 }
1110 } else if (postvalid) {
Daniel Veillarda37aab82003-06-09 09:10:36 +00001111 xmlValidCtxtPtr cvp;
1112
1113 if ((cvp = xmlNewValidCtxt()) == NULL) {
1114 xmlGenericError(xmlGenericErrorContext,
1115 "Couldn't allocate validation context\n");
1116 exit(-1);
1117 }
1118
Daniel Veillard48b2f892001-02-25 16:11:03 +00001119 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001120 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001121 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00001122 cvp->userData = (void *) stderr;
1123 cvp->error = (xmlValidityErrorFunc) fprintf;
1124 cvp->warning = (xmlValidityWarningFunc) fprintf;
1125 if (!xmlValidateDocument(cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001126 xmlGenericError(xmlGenericErrorContext,
1127 "Document %s does not validate\n", filename);
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001128 progresult = 3;
Daniel Veillardcd429612000-10-11 15:57:05 +00001129 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001130 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001131 endTimer("Validating");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001132 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00001133 xmlFreeValidCtxt(cvp);
Daniel Veillard71531f32003-02-05 13:19:53 +00001134#ifdef LIBXML_SCHEMAS_ENABLED
1135 } else if (relaxngschemas != NULL) {
1136 xmlRelaxNGValidCtxtPtr ctxt;
1137 int ret;
1138
Daniel Veillard42f12e92003-03-07 18:32:59 +00001139 if ((timing) && (!repeat)) {
1140 startTimer();
1141 }
1142
Daniel Veillard71531f32003-02-05 13:19:53 +00001143 ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
1144 xmlRelaxNGSetValidErrors(ctxt,
1145 (xmlRelaxNGValidityErrorFunc) fprintf,
1146 (xmlRelaxNGValidityWarningFunc) fprintf,
1147 stderr);
1148 ret = xmlRelaxNGValidateDoc(ctxt, doc);
1149 if (ret == 0) {
1150 printf("%s validates\n", filename);
1151 } else if (ret > 0) {
1152 printf("%s fails to validate\n", filename);
1153 } else {
1154 printf("%s validation generated an internal error\n",
1155 filename);
1156 }
1157 xmlRelaxNGFreeValidCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00001158 if ((timing) && (!repeat)) {
1159 endTimer("Validating");
1160 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001161 } else if (wxschemas != NULL) {
1162 xmlSchemaValidCtxtPtr ctxt;
1163 int ret;
1164
1165 if ((timing) && (!repeat)) {
1166 startTimer();
1167 }
1168
1169 ctxt = xmlSchemaNewValidCtxt(wxschemas);
1170 xmlSchemaSetValidErrors(ctxt,
1171 (xmlSchemaValidityErrorFunc) fprintf,
1172 (xmlSchemaValidityWarningFunc) fprintf,
1173 stderr);
1174 ret = xmlSchemaValidateDoc(ctxt, doc);
1175 if (ret == 0) {
1176 printf("%s validates\n", filename);
1177 } else if (ret > 0) {
1178 printf("%s fails to validate\n", filename);
1179 } else {
1180 printf("%s validation generated an internal error\n",
1181 filename);
1182 }
1183 xmlSchemaFreeValidCtxt(ctxt);
1184 if ((timing) && (!repeat)) {
1185 endTimer("Validating");
1186 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001187#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001188 }
1189
1190#ifdef LIBXML_DEBUG_ENABLED
1191 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001192 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001193#endif
1194
1195 /*
1196 * free it.
1197 */
Daniel Veillard48b2f892001-02-25 16:11:03 +00001198 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001199 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001200 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001201 xmlFreeDoc(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +00001202 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001203 endTimer("Freeing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001204 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001205}
1206
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001207/************************************************************************
1208 * *
1209 * Usage and Main *
1210 * *
1211 ************************************************************************/
1212
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00001213static void showVersion(const char *name) {
1214 fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
1215 fprintf(stderr, " compiled with: ");
1216#ifdef LIBXML_FTP_ENABLED
1217 fprintf(stderr, "FTP ");
1218#endif
1219#ifdef LIBXML_HTTP_ENABLED
1220 fprintf(stderr, "HTTP ");
1221#endif
1222#ifdef LIBXML_HTML_ENABLED
1223 fprintf(stderr, "HTML ");
1224#endif
1225#ifdef LIBXML_C14N_ENABLED
1226 fprintf(stderr, "C14N ");
1227#endif
1228#ifdef LIBXML_CATALOG_ENABLED
1229 fprintf(stderr, "Catalog ");
1230#endif
1231#ifdef LIBXML_DOCB_ENABLED
1232 fprintf(stderr, "DocBook ");
1233#endif
1234#ifdef LIBXML_XPATH_ENABLED
1235 fprintf(stderr, "XPath ");
1236#endif
1237#ifdef LIBXML_XPTR_ENABLED
1238 fprintf(stderr, "XPointer ");
1239#endif
1240#ifdef LIBXML_XINCLUDE_ENABLED
1241 fprintf(stderr, "XInclude ");
1242#endif
1243#ifdef LIBXML_ICONV_ENABLED
1244 fprintf(stderr, "Iconv ");
1245#endif
1246#ifdef DEBUG_MEMORY_LOCATION
1247 fprintf(stderr, "MemDebug ");
1248#endif
1249#ifdef LIBXML_UNICODE_ENABLED
1250 fprintf(stderr, "Unicode ");
1251#endif
1252#ifdef LIBXML_REGEXP_ENABLED
1253 fprintf(stderr, "Regexps ");
1254#endif
1255#ifdef LIBXML_AUTOMATA_ENABLED
1256 fprintf(stderr, "Automata ");
1257#endif
1258#ifdef LIBXML_SCHEMAS_ENABLED
1259 fprintf(stderr, "Schemas ");
1260#endif
1261 fprintf(stderr, "\n");
1262}
1263
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001264static void usage(const char *name) {
1265 printf("Usage : %s [options] XMLfiles ...\n", name);
1266 printf("\tParse the XML files and output the result of the parsing\n");
1267 printf("\t--version : display the version of the XML library used\n");
1268#ifdef LIBXML_DEBUG_ENABLED
1269 printf("\t--debug : dump a debug tree of the in-memory document\n");
1270 printf("\t--shell : run a navigating shell\n");
1271 printf("\t--debugent : debug the entities defined in the document\n");
Daniel Veillard8326e732003-01-07 00:19:07 +00001272#else
1273 printf("\t--debug : dump the nodes content when using --stream\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001274#endif
1275 printf("\t--copy : used to test the internal copy implementation\n");
1276 printf("\t--recover : output what was parsable on broken XML documents\n");
1277 printf("\t--noent : substitute entity references by their value\n");
1278 printf("\t--noout : don't output the result tree\n");
Daniel Veillarde8b09e42003-05-13 22:14:13 +00001279 printf("\t--nonet : refuse to fetch DTDs or entities over network\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001280 printf("\t--htmlout : output results as HTML\n");
Daniel Veillard05c13a22001-09-09 08:38:09 +00001281 printf("\t--nowrap : do not put HTML doc wrapper\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001282 printf("\t--valid : validate the document in addition to std well-formed check\n");
1283 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
1284 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
1285 printf("\t--timing : print some timings\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001286 printf("\t--output file or -o file: save to a given file\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001287 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
1288 printf("\t--insert : ad-hoc test for valid insertions\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001289#ifdef HAVE_ZLIB_H
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001290 printf("\t--compress : turn on gzip compression of output\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001291#endif
Daniel Veillard89cad532001-10-22 09:46:13 +00001292#ifdef LIBXML_DOCB_ENABLED
1293 printf("\t--sgml : use the DocBook SGML parser\n");
1294#endif
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001295#ifdef LIBXML_HTML_ENABLED
1296 printf("\t--html : use the HTML parser\n");
1297#endif
1298 printf("\t--push : use the push mode of the parser\n");
1299#ifdef HAVE_SYS_MMAN_H
1300 printf("\t--memory : parse from memory\n");
1301#endif
1302 printf("\t--nowarning : do not emit warnings from parser/validator\n");
1303 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
Daniel Veillard90493a92001-08-14 14:12:47 +00001304 printf("\t--format : reformat/reindent the input\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001305 printf("\t--testIO : test user I/O support\n");
1306 printf("\t--encode encoding : output in the given encoding\n");
1307#ifdef LIBXML_CATALOG_ENABLED
Daniel Veillardbd9b0e82001-11-26 10:32:08 +00001308 printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
1309 printf("\t otherwise XML Catalogs starting from \n");
Daniel Veillard3be27512003-01-26 19:49:04 +00001310 printf("\t " XML_XML_DEFAULT_CATALOG " are activated by default\n");
Daniel Veillard05c13a22001-09-09 08:38:09 +00001311 printf("\t--nocatalogs: deactivate all catalogs\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001312#endif
1313 printf("\t--auto : generate a small doc on the fly\n");
1314#ifdef LIBXML_XINCLUDE_ENABLED
1315 printf("\t--xinclude : do XInclude processing\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001316#endif
Daniel Veillardcbaf3992001-12-31 16:16:02 +00001317 printf("\t--loaddtd : fetch external DTD\n");
Daniel Veillard48da9102001-08-07 01:10:10 +00001318 printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
Daniel Veillard29e43992001-12-13 22:21:58 +00001319 printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
Daniel Veillard7704fb12003-01-03 16:19:51 +00001320 printf("\t--stream : use the streaming interface to process very large files\n");
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001321 printf("\t--chkregister : verify the node registration code\n");
Daniel Veillardef4d3bc2003-02-07 12:38:22 +00001322#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard71531f32003-02-05 13:19:53 +00001323 printf("\t--relaxng schema : do RelaxNG validation against the schema\n");
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001324 printf("\t--schema schema : do validation against the WXS schema\n");
Daniel Veillard71531f32003-02-05 13:19:53 +00001325#endif
Daniel Veillarda42f25f2002-01-25 14:15:40 +00001326 printf("\nLibxml project home page: http://xmlsoft.org/\n");
1327 printf("To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001328}
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001329
1330static void registerNode(xmlNodePtr node)
1331{
1332 node->_private = malloc(sizeof(long));
1333 *(long*)node->_private = (long) 0x81726354;
1334}
1335
1336static void deregisterNode(xmlNodePtr node)
1337{
1338 assert(node->_private != NULL);
1339 assert(*(long*)node->_private == (long) 0x81726354);
1340 free(node->_private);
1341}
1342
Daniel Veillard4a6845d2001-01-03 13:32:39 +00001343int
1344main(int argc, char **argv) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00001345 int i, acount;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001346 int files = 0;
Daniel Veillard845cce42002-01-09 11:51:37 +00001347 int version = 0;
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00001348 const char* indent;
1349
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001350 if (argc <= 1) {
1351 usage(argv[0]);
1352 return(1);
1353 }
Daniel Veillardbe803962000-06-28 23:40:59 +00001354 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001355 for (i = 1; i < argc ; i++) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001356 if (!strcmp(argv[i], "-"))
1357 break;
1358
1359 if (argv[i][0] != '-')
1360 continue;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001361 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
1362 debug++;
Daniel Veillard56ada1d2003-01-07 11:17:25 +00001363 else
1364#ifdef LIBXML_DEBUG_ENABLED
1365 if ((!strcmp(argv[i], "-shell")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001366 (!strcmp(argv[i], "--shell"))) {
1367 shell++;
1368 noout = 1;
1369 } else
1370#endif
1371 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
1372 copy++;
1373 else if ((!strcmp(argv[i], "-recover")) ||
1374 (!strcmp(argv[i], "--recover")))
1375 recovery++;
1376 else if ((!strcmp(argv[i], "-noent")) ||
1377 (!strcmp(argv[i], "--noent")))
1378 noent++;
Daniel Veillard4ec885a2001-06-17 10:31:07 +00001379 else if ((!strcmp(argv[i], "-version")) ||
Daniel Veillard845cce42002-01-09 11:51:37 +00001380 (!strcmp(argv[i], "--version"))) {
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00001381 showVersion(argv[0]);
Daniel Veillard845cce42002-01-09 11:51:37 +00001382 version = 1;
1383 } else if ((!strcmp(argv[i], "-noout")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001384 (!strcmp(argv[i], "--noout")))
1385 noout++;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001386 else if ((!strcmp(argv[i], "-o")) ||
1387 (!strcmp(argv[i], "-output")) ||
1388 (!strcmp(argv[i], "--output"))) {
1389 i++;
Daniel Veillard6e4f1c02002-04-09 09:55:20 +00001390 output = argv[i];
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001391 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001392 else if ((!strcmp(argv[i], "-htmlout")) ||
1393 (!strcmp(argv[i], "--htmlout")))
1394 htmlout++;
Daniel Veillard89cad532001-10-22 09:46:13 +00001395#ifdef LIBXML_DOCB_ENABLED
1396 else if ((!strcmp(argv[i], "-sgml")) ||
1397 (!strcmp(argv[i], "--sgml"))) {
1398 sgml++;
1399 }
1400#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001401#ifdef LIBXML_HTML_ENABLED
1402 else if ((!strcmp(argv[i], "-html")) ||
1403 (!strcmp(argv[i], "--html"))) {
1404 html++;
1405 }
1406#endif /* LIBXML_HTML_ENABLED */
1407 else if ((!strcmp(argv[i], "-nowrap")) ||
1408 (!strcmp(argv[i], "--nowrap")))
1409 nowrap++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001410 else if ((!strcmp(argv[i], "-loaddtd")) ||
1411 (!strcmp(argv[i], "--loaddtd")))
1412 loaddtd++;
Daniel Veillard48da9102001-08-07 01:10:10 +00001413 else if ((!strcmp(argv[i], "-dtdattr")) ||
1414 (!strcmp(argv[i], "--dtdattr"))) {
1415 loaddtd++;
1416 dtdattrs++;
1417 } else if ((!strcmp(argv[i], "-valid")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001418 (!strcmp(argv[i], "--valid")))
1419 valid++;
1420 else if ((!strcmp(argv[i], "-postvalid")) ||
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001421 (!strcmp(argv[i], "--postvalid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001422 postvalid++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001423 loaddtd++;
1424 } else if ((!strcmp(argv[i], "-dtdvalid")) ||
Daniel Veillardcd429612000-10-11 15:57:05 +00001425 (!strcmp(argv[i], "--dtdvalid"))) {
1426 i++;
1427 dtdvalid = argv[i];
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001428 loaddtd++;
Daniel Veillardcd429612000-10-11 15:57:05 +00001429 }
Daniel Veillard29e43992001-12-13 22:21:58 +00001430 else if ((!strcmp(argv[i], "-dropdtd")) ||
1431 (!strcmp(argv[i], "--dropdtd")))
1432 dropdtd++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001433 else if ((!strcmp(argv[i], "-insert")) ||
1434 (!strcmp(argv[i], "--insert")))
1435 insert++;
Daniel Veillard48b2f892001-02-25 16:11:03 +00001436 else if ((!strcmp(argv[i], "-timing")) ||
1437 (!strcmp(argv[i], "--timing")))
1438 timing++;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001439 else if ((!strcmp(argv[i], "-auto")) ||
1440 (!strcmp(argv[i], "--auto")))
1441 generate++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001442 else if ((!strcmp(argv[i], "-repeat")) ||
1443 (!strcmp(argv[i], "--repeat")))
1444 repeat++;
1445 else if ((!strcmp(argv[i], "-push")) ||
1446 (!strcmp(argv[i], "--push")))
1447 push++;
Daniel Veillard46e370e2000-07-21 20:32:03 +00001448#ifdef HAVE_SYS_MMAN_H
1449 else if ((!strcmp(argv[i], "-memory")) ||
1450 (!strcmp(argv[i], "--memory")))
1451 memory++;
1452#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +00001453 else if ((!strcmp(argv[i], "-testIO")) ||
1454 (!strcmp(argv[i], "--testIO")))
1455 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00001456#ifdef LIBXML_XINCLUDE_ENABLED
1457 else if ((!strcmp(argv[i], "-xinclude")) ||
1458 (!strcmp(argv[i], "--xinclude")))
1459 xinclude++;
1460#endif
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001461#ifdef HAVE_ZLIB_H
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001462 else if ((!strcmp(argv[i], "-compress")) ||
1463 (!strcmp(argv[i], "--compress"))) {
1464 compress++;
1465 xmlSetCompressMode(9);
1466 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001467#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001468 else if ((!strcmp(argv[i], "-nowarning")) ||
1469 (!strcmp(argv[i], "--nowarning"))) {
1470 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001471 xmlPedanticParserDefault(0);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001472 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001473 else if ((!strcmp(argv[i], "-pedantic")) ||
1474 (!strcmp(argv[i], "--pedantic"))) {
1475 xmlGetWarningsDefaultValue = 1;
1476 xmlPedanticParserDefault(1);
1477 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00001478#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001479 else if ((!strcmp(argv[i], "-debugent")) ||
1480 (!strcmp(argv[i], "--debugent"))) {
1481 debugent++;
1482 xmlParserDebugEntities = 1;
1483 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00001484#endif
Daniel Veillard81418e32001-05-22 15:08:55 +00001485#ifdef LIBXML_CATALOG_ENABLED
1486 else if ((!strcmp(argv[i], "-catalogs")) ||
1487 (!strcmp(argv[i], "--catalogs"))) {
Daniel Veillarde2940dd2001-08-22 00:06:49 +00001488 catalogs++;
1489 } else if ((!strcmp(argv[i], "-nocatalogs")) ||
1490 (!strcmp(argv[i], "--nocatalogs"))) {
1491 nocatalogs++;
Daniel Veillard81418e32001-05-22 15:08:55 +00001492 }
1493#endif
Daniel Veillardbe803962000-06-28 23:40:59 +00001494 else if ((!strcmp(argv[i], "-encode")) ||
1495 (!strcmp(argv[i], "--encode"))) {
1496 i++;
1497 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001498 /*
1499 * OK it's for testing purposes
1500 */
1501 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +00001502 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001503 else if ((!strcmp(argv[i], "-noblanks")) ||
1504 (!strcmp(argv[i], "--noblanks"))) {
1505 noblanks++;
1506 xmlKeepBlanksDefault(0);
Daniel Veillard90493a92001-08-14 14:12:47 +00001507 }
1508 else if ((!strcmp(argv[i], "-format")) ||
1509 (!strcmp(argv[i], "--format"))) {
1510 noblanks++;
1511 format++;
1512 xmlKeepBlanksDefault(0);
Daniel Veillard7704fb12003-01-03 16:19:51 +00001513 }
1514 else if ((!strcmp(argv[i], "-stream")) ||
1515 (!strcmp(argv[i], "--stream"))) {
1516 stream++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001517 }
1518 else if ((!strcmp(argv[i], "-chkregister")) ||
1519 (!strcmp(argv[i], "--chkregister"))) {
1520 chkregister++;
Daniel Veillard71531f32003-02-05 13:19:53 +00001521#ifdef LIBXML_SCHEMAS_ENABLED
1522 } else if ((!strcmp(argv[i], "-relaxng")) ||
1523 (!strcmp(argv[i], "--relaxng"))) {
1524 i++;
1525 relaxng = argv[i];
1526 noent++;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001527 } else if ((!strcmp(argv[i], "-schema")) ||
1528 (!strcmp(argv[i], "--schema"))) {
1529 i++;
1530 schema = argv[i];
1531 noent++;
Daniel Veillard71531f32003-02-05 13:19:53 +00001532#endif
Daniel Veillarde8b09e42003-05-13 22:14:13 +00001533 } else if ((!strcmp(argv[i], "-nonet")) ||
1534 (!strcmp(argv[i], "--nonet"))) {
1535 xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001536 } else {
1537 fprintf(stderr, "Unknown option %s\n", argv[i]);
1538 usage(argv[0]);
1539 return(1);
1540 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001541 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00001542
1543#ifdef LIBXML_CATALOG_ENABLED
1544 if (nocatalogs == 0) {
1545 if (catalogs) {
1546 const char *catal;
1547
1548 catal = getenv("SGML_CATALOG_FILES");
Daniel Veillard6c5f9d12001-08-25 13:33:14 +00001549 if (catal != NULL) {
1550 xmlLoadCatalogs(catal);
1551 } else {
1552 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
1553 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00001554 }
1555 }
1556#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001557
1558 if (chkregister) {
1559 xmlRegisterNodeDefault(registerNode);
1560 xmlDeregisterNodeDefault(deregisterNode);
1561 }
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00001562
1563 indent = getenv("XMLLINT_INDENT");
1564 if(indent != NULL) {
1565 xmlTreeIndentString = indent;
1566 }
1567
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001568
Daniel Veillardd9bad132001-07-23 19:39:43 +00001569 xmlLineNumbersDefault(1);
Daniel Veillard48da9102001-08-07 01:10:10 +00001570 if (loaddtd != 0)
1571 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
1572 if (dtdattrs)
1573 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001574 if (noent != 0) xmlSubstituteEntitiesDefault(1);
1575 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
1576 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001577 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001578 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001579 xmlGenericError(xmlGenericErrorContext,
1580 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
1581 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001582 "<html><head><title>%s output</title></head>\n",
1583 argv[0]);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001584 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001585 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
1586 argv[0]);
1587 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001588
1589#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +00001590 if ((relaxng != NULL) && (stream == 0)) {
Daniel Veillard71531f32003-02-05 13:19:53 +00001591 xmlRelaxNGParserCtxtPtr ctxt;
1592
Daniel Veillardce192eb2003-04-16 15:58:05 +00001593 /* forces loading the DTDs */
1594 xmlLoadExtDtdDefaultValue |= 1;
Daniel Veillard42f12e92003-03-07 18:32:59 +00001595 if (timing) {
1596 startTimer();
1597 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001598 ctxt = xmlRelaxNGNewParserCtxt(relaxng);
1599 xmlRelaxNGSetParserErrors(ctxt,
1600 (xmlRelaxNGValidityErrorFunc) fprintf,
1601 (xmlRelaxNGValidityWarningFunc) fprintf,
1602 stderr);
1603 relaxngschemas = xmlRelaxNGParse(ctxt);
Daniel Veillardce192eb2003-04-16 15:58:05 +00001604 if (relaxngschemas == NULL) {
1605 xmlGenericError(xmlGenericErrorContext,
1606 "Relax-NG schema %s failed to compile\n", relaxng);
1607 relaxng = NULL;
1608 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001609 xmlRelaxNGFreeParserCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00001610 if (timing) {
1611 endTimer("Compiling the schemas");
1612 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001613 } else if ((schema != NULL) && (stream == 0)) {
1614 xmlSchemaParserCtxtPtr ctxt;
1615
1616 if (timing) {
1617 startTimer();
1618 }
1619 ctxt = xmlSchemaNewParserCtxt(schema);
1620 xmlSchemaSetParserErrors(ctxt,
1621 (xmlSchemaValidityErrorFunc) fprintf,
1622 (xmlSchemaValidityWarningFunc) fprintf,
1623 stderr);
1624 wxschemas = xmlSchemaParse(ctxt);
1625 if (wxschemas == NULL) {
1626 xmlGenericError(xmlGenericErrorContext,
1627 "WXS schema %s failed to compile\n", schema);
1628 schema = NULL;
1629 }
1630 xmlSchemaFreeParserCtxt(ctxt);
1631 if (timing) {
1632 endTimer("Compiling the schemas");
1633 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001634 }
1635#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001636 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +00001637 if ((!strcmp(argv[i], "-encode")) ||
1638 (!strcmp(argv[i], "--encode"))) {
1639 i++;
1640 continue;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001641 } else if ((!strcmp(argv[i], "-o")) ||
1642 (!strcmp(argv[i], "-output")) ||
1643 (!strcmp(argv[i], "--output"))) {
1644 i++;
1645 continue;
Daniel Veillardbe803962000-06-28 23:40:59 +00001646 }
Daniel Veillardcd429612000-10-11 15:57:05 +00001647 if ((!strcmp(argv[i], "-dtdvalid")) ||
1648 (!strcmp(argv[i], "--dtdvalid"))) {
1649 i++;
1650 continue;
1651 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001652 if ((!strcmp(argv[i], "-relaxng")) ||
1653 (!strcmp(argv[i], "--relaxng"))) {
1654 i++;
1655 continue;
1656 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001657 if ((!strcmp(argv[i], "-schema")) ||
1658 (!strcmp(argv[i], "--schema"))) {
1659 i++;
1660 continue;
1661 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001662 if ((timing) && (repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00001663 startTimer();
Daniel Veillardcbaf3992001-12-31 16:16:02 +00001664 /* Remember file names. "-" means stdin. <sven@zen.org> */
Daniel Veillard4a6845d2001-01-03 13:32:39 +00001665 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001666 if (repeat) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00001667 for (acount = 0;acount < 100 * repeat;acount++)
1668 if (stream != 0)
1669 streamFile(argv[i]);
1670 else
1671 parseAndPrintFile(argv[i]);
1672 } else {
1673 if (stream != 0)
1674 streamFile(argv[i]);
1675 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001676 parseAndPrintFile(argv[i]);
Daniel Veillard7704fb12003-01-03 16:19:51 +00001677 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001678 files ++;
Daniel Veillarda7866932001-12-04 13:14:44 +00001679 if ((timing) && (repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001680 endTimer("100 iterations");
Daniel Veillarda7866932001-12-04 13:14:44 +00001681 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001682 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001683 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001684 if (generate)
1685 parseAndPrintFile(NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001686 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001687 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001688 }
Daniel Veillard845cce42002-01-09 11:51:37 +00001689 if ((files == 0) && (!generate) && (version == 0)) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001690 usage(argv[0]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001691 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001692#ifdef LIBXML_SCHEMAS_ENABLED
1693 if (relaxngschemas != NULL)
1694 xmlRelaxNGFree(relaxngschemas);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001695 if (wxschemas != NULL)
1696 xmlSchemaFree(wxschemas);
Daniel Veillard71531f32003-02-05 13:19:53 +00001697 xmlRelaxNGCleanupTypes();
1698#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001699 xmlCleanupParser();
1700 xmlMemoryDump();
1701
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001702 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001703}
Daniel Veillard88a172f2000-08-04 18:23:10 +00001704