blob: 100a83d4a76f6fca5cd211c98220930f177ab6ff [file] [log] [blame]
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001/*
2 * xmllint.c : a small tester program for XML input.
3 *
4 * See Copyright for the status of this software.
5 *
Daniel Veillardc5d64342001-06-24 12:13:24 +00006 * daniel@veillard.com
Daniel Veillardce8b83b2000-04-05 18:38:42 +00007 */
8
Bjorn Reese70a9da52001-04-21 16:57:29 +00009#include "libxml.h"
Daniel Veillardce8b83b2000-04-05 18:38:42 +000010
Daniel Veillardce8b83b2000-04-05 18:38:42 +000011#include <string.h>
Daniel Veillardce8b83b2000-04-05 18:38:42 +000012#include <stdarg.h>
Daniel Veillard8a1b1852003-01-05 22:37:17 +000013#include <assert.h>
14
Daniel Veillard3c5ed912002-01-08 10:36:16 +000015#if defined (_WIN32) && !defined(__CYGWIN__)
Daniel Veillard07cb8222003-09-10 10:51:05 +000016#if defined (_MSC_VER) || defined(__BORLANDC__)
Daniel Veillard2d90de42001-04-16 17:46:18 +000017#include <winsock2.h>
18#pragma comment(lib, "ws2_32.lib")
19#define gettimeofday(p1,p2)
20#endif /* _MSC_VER */
Igor Zlatkovic19b87642003-08-28 12:32:04 +000021#endif /* _WIN32 */
22
Daniel Veillarded472f32001-12-13 08:48:14 +000023#ifdef HAVE_SYS_TIME_H
Daniel Veillard48b2f892001-02-25 16:11:03 +000024#include <sys/time.h>
Daniel Veillarded472f32001-12-13 08:48:14 +000025#endif
Daniel Veillard01db67c2001-12-18 07:09:59 +000026#ifdef HAVE_TIME_H
27#include <time.h>
28#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +000029
Daniel Veillard1638a472003-08-14 01:23:25 +000030#ifdef __MINGW32__
31#define _WINSOCKAPI_
32#include <wsockcompat.h>
33#include <winsock2.h>
34#undef SOCKLEN_T
35#define SOCKLEN_T unsigned int
36#endif
37
Daniel Veillard90bc3712002-03-07 15:12:58 +000038#ifdef HAVE_SYS_TIMEB_H
39#include <sys/timeb.h>
40#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000041
42#ifdef HAVE_SYS_TYPES_H
43#include <sys/types.h>
44#endif
45#ifdef HAVE_SYS_STAT_H
46#include <sys/stat.h>
47#endif
48#ifdef HAVE_FCNTL_H
49#include <fcntl.h>
50#endif
51#ifdef HAVE_UNISTD_H
52#include <unistd.h>
53#endif
Daniel Veillard46e370e2000-07-21 20:32:03 +000054#ifdef HAVE_SYS_MMAN_H
55#include <sys/mman.h>
Daniel Veillard87b95392000-08-12 21:12:04 +000056/* seems needed for Solaris */
57#ifndef MAP_FAILED
58#define MAP_FAILED ((void *) -1)
59#endif
Daniel Veillard46e370e2000-07-21 20:32:03 +000060#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000061#ifdef HAVE_STDLIB_H
62#include <stdlib.h>
63#endif
64#ifdef HAVE_LIBREADLINE
65#include <readline/readline.h>
66#ifdef HAVE_LIBHISTORY
67#include <readline/history.h>
68#endif
69#endif
70
71#include <libxml/xmlmemory.h>
72#include <libxml/parser.h>
73#include <libxml/parserInternals.h>
74#include <libxml/HTMLparser.h>
75#include <libxml/HTMLtree.h>
76#include <libxml/tree.h>
77#include <libxml/xpath.h>
78#include <libxml/debugXML.h>
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +000079#include <libxml/xmlerror.h>
Daniel Veillard9e8bfae2000-11-06 16:43:11 +000080#ifdef LIBXML_XINCLUDE_ENABLED
81#include <libxml/xinclude.h>
82#endif
Daniel Veillard81418e32001-05-22 15:08:55 +000083#ifdef LIBXML_CATALOG_ENABLED
84#include <libxml/catalog.h>
85#endif
Daniel Veillard3c01b1d2001-10-17 15:58:35 +000086#include <libxml/globals.h>
Daniel Veillard7704fb12003-01-03 16:19:51 +000087#include <libxml/xmlreader.h>
Daniel Veillard71531f32003-02-05 13:19:53 +000088#ifdef LIBXML_SCHEMAS_ENABLED
89#include <libxml/relaxng.h>
Daniel Veillard75bb3bb2003-05-12 15:25:56 +000090#include <libxml/xmlschemas.h>
Daniel Veillard71531f32003-02-05 13:19:53 +000091#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000092
Daniel Veillard3be27512003-01-26 19:49:04 +000093#ifndef XML_XML_DEFAULT_CATALOG
94#define XML_XML_DEFAULT_CATALOG "file:///etc/xml/catalog"
95#endif
96
Daniel Veillardce8b83b2000-04-05 18:38:42 +000097#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +000098static int shell = 0;
99static int debugent = 0;
100#endif
Daniel Veillard8326e732003-01-07 00:19:07 +0000101static int debug = 0;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000102static int copy = 0;
103static int recovery = 0;
104static int noent = 0;
105static int noout = 0;
106static int nowrap = 0;
107static int valid = 0;
108static int postvalid = 0;
Daniel Veillardcd429612000-10-11 15:57:05 +0000109static char * dtdvalid = NULL;
Daniel Veillard66f68e72003-08-18 16:39:51 +0000110static char * dtdvalidfpi = NULL;
Daniel Veillard71531f32003-02-05 13:19:53 +0000111#ifdef LIBXML_SCHEMAS_ENABLED
112static char * relaxng = NULL;
113static xmlRelaxNGPtr relaxngschemas = NULL;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +0000114static char * schema = NULL;
115static xmlSchemaPtr wxschemas = NULL;
Daniel Veillard71531f32003-02-05 13:19:53 +0000116#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000117static int repeat = 0;
118static int insert = 0;
119static int compress = 0;
120static int html = 0;
121static int htmlout = 0;
122static int push = 0;
Daniel Veillard46e370e2000-07-21 20:32:03 +0000123#ifdef HAVE_SYS_MMAN_H
124static int memory = 0;
125#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000126static int noblanks = 0;
Daniel Veillard90493a92001-08-14 14:12:47 +0000127static int format = 0;
Daniel Veillard5e873c42000-04-12 13:27:38 +0000128static int testIO = 0;
Daniel Veillardbe803962000-06-28 23:40:59 +0000129static char *encoding = NULL;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000130#ifdef LIBXML_XINCLUDE_ENABLED
131static int xinclude = 0;
132#endif
Daniel Veillard48da9102001-08-07 01:10:10 +0000133static int dtdattrs = 0;
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000134static int loaddtd = 0;
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000135static int progresult = 0;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000136static int timing = 0;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000137static int generate = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000138static int dropdtd = 0;
Daniel Veillarde2940dd2001-08-22 00:06:49 +0000139#ifdef LIBXML_CATALOG_ENABLED
140static int catalogs = 0;
141static int nocatalogs = 0;
142#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +0000143static int stream = 0;
Daniel Veillard8a1b1852003-01-05 22:37:17 +0000144static int chkregister = 0;
Daniel Veillard07cb8222003-09-10 10:51:05 +0000145static int sax1 = 0;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +0000146static const char *output = NULL;
147
Daniel Veillard01db67c2001-12-18 07:09:59 +0000148/*
149 * Internal timing routines to remove the necessity to have unix-specific
150 * function calls
151 */
152
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000153#ifndef HAVE_GETTIMEOFDAY
154#ifdef HAVE_SYS_TIMEB_H
155#ifdef HAVE_SYS_TIME_H
156#ifdef HAVE_FTIME
157
Daniel Veillard01c13b52002-12-10 15:19:08 +0000158static int
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000159my_gettimeofday(struct timeval *tvp, void *tzp)
160{
161 struct timeb timebuffer;
162
163 ftime(&timebuffer);
164 if (tvp) {
165 tvp->tv_sec = timebuffer.time;
166 tvp->tv_usec = timebuffer.millitm * 1000L;
167 }
168 return (0);
169}
170#define HAVE_GETTIMEOFDAY 1
171#define gettimeofday my_gettimeofday
172
173#endif /* HAVE_FTIME */
174#endif /* HAVE_SYS_TIME_H */
175#endif /* HAVE_SYS_TIMEB_H */
176#endif /* !HAVE_GETTIMEOFDAY */
177
Daniel Veillard01db67c2001-12-18 07:09:59 +0000178#if defined(HAVE_GETTIMEOFDAY)
179static struct timeval begin, end;
180
181/*
182 * startTimer: call where you want to start timing
183 */
184static void
185startTimer(void)
186{
187 gettimeofday(&begin, NULL);
188}
189
190/*
191 * endTimer: call where you want to stop timing and to print out a
192 * message about the timing performed; format is a printf
193 * type argument
194 */
195static void
Daniel Veillard118aed72002-09-24 14:13:13 +0000196endTimer(const char *fmt, ...)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000197{
198 long msec;
199 va_list ap;
200
201 gettimeofday(&end, NULL);
202 msec = end.tv_sec - begin.tv_sec;
203 msec *= 1000;
204 msec += (end.tv_usec - begin.tv_usec) / 1000;
205
206#ifndef HAVE_STDARG_H
207#error "endTimer required stdarg functions"
208#endif
Daniel Veillard118aed72002-09-24 14:13:13 +0000209 va_start(ap, fmt);
210 vfprintf(stderr, fmt, ap);
Daniel Veillard01db67c2001-12-18 07:09:59 +0000211 va_end(ap);
212
213 fprintf(stderr, " took %ld ms\n", msec);
214}
215#elif defined(HAVE_TIME_H)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000216/*
217 * No gettimeofday function, so we have to make do with calling clock.
218 * This is obviously less accurate, but there's little we can do about
219 * that.
220 */
Daniel Veillard90bc3712002-03-07 15:12:58 +0000221#ifndef CLOCKS_PER_SEC
222#define CLOCKS_PER_SEC 100
223#endif
Daniel Veillard01db67c2001-12-18 07:09:59 +0000224
225static clock_t begin, end;
226static void
227startTimer(void)
228{
229 begin = clock();
230}
231static void
232endTimer(const char *fmt, ...)
233{
234 long msec;
235 va_list ap;
236
237 end = clock();
238 msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
239
240#ifndef HAVE_STDARG_H
241#error "endTimer required stdarg functions"
242#endif
243 va_start(ap, fmt);
244 vfprintf(stderr, fmt, ap);
245 va_end(ap);
246 fprintf(stderr, " took %ld ms\n", msec);
247}
248#else
249
250/*
251 * We don't have a gettimeofday or time.h, so we just don't do timing
252 */
253static void
254startTimer(void)
255{
256 /*
257 * Do nothing
258 */
259}
260static void
261endTimer(char *format, ...)
262{
263 /*
264 * We cannot do anything because we don't have a timing function
265 */
266#ifdef HAVE_STDARG_H
267 va_start(ap, format);
268 vfprintf(stderr, format, ap);
269 va_end(ap);
270 fprintf(stderr, " was not timed\n", msec);
271#else
272 /* We don't have gettimeofday, time or stdarg.h, what crazy world is
273 * this ?!
274 */
275#endif
276}
277#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000278/************************************************************************
279 * *
280 * HTML ouput *
281 * *
282 ************************************************************************/
283char buffer[50000];
284
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000285static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000286xmlHTMLEncodeSend(void) {
287 char *result;
288
289 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
290 if (result) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000291 xmlGenericError(xmlGenericErrorContext, "%s", result);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000292 xmlFree(result);
293 }
294 buffer[0] = 0;
295}
296
297/**
298 * xmlHTMLPrintFileInfo:
299 * @input: an xmlParserInputPtr input
300 *
301 * Displays the associated file and line informations for the current input
302 */
303
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000304static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000305xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000306 int len;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000307 xmlGenericError(xmlGenericErrorContext, "<p>");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000308
309 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000310 if (input != NULL) {
311 if (input->filename) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000312 snprintf(&buffer[len], sizeof(buffer) - len, "%s:%d: ", input->filename,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000313 input->line);
314 } else {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000315 snprintf(&buffer[len], sizeof(buffer) - len, "Entity: line %d: ", input->line);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000316 }
317 }
318 xmlHTMLEncodeSend();
319}
320
321/**
322 * xmlHTMLPrintFileContext:
323 * @input: an xmlParserInputPtr input
324 *
325 * Displays current context within the input content for error tracking
326 */
327
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000328static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000329xmlHTMLPrintFileContext(xmlParserInputPtr input) {
330 const xmlChar *cur, *base;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000331 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000332 int n;
333
334 if (input == NULL) return;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000335 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000336 cur = input->cur;
337 base = input->base;
338 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
339 cur--;
340 }
341 n = 0;
342 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
343 cur--;
344 if ((*cur == '\n') || (*cur == '\r')) cur++;
345 base = cur;
346 n = 0;
347 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000348 len = strlen(buffer);
349 snprintf(&buffer[len], sizeof(buffer) - len, "%c",
350 (unsigned char) *cur++);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000351 n++;
352 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000353 len = strlen(buffer);
354 snprintf(&buffer[len], sizeof(buffer) - len, "\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000355 cur = input->cur;
356 while ((*cur == '\n') || (*cur == '\r'))
357 cur--;
358 n = 0;
359 while ((cur != base) && (n++ < 80)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000360 len = strlen(buffer);
361 snprintf(&buffer[len], sizeof(buffer) - len, " ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000362 base++;
363 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000364 len = strlen(buffer);
365 snprintf(&buffer[len], sizeof(buffer) - len, "^\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000366 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000367 xmlGenericError(xmlGenericErrorContext, "</pre>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000368}
369
370/**
371 * xmlHTMLError:
372 * @ctx: an XML parser context
373 * @msg: the message to display/transmit
374 * @...: extra parameters for the message display
375 *
376 * Display and format an error messages, gives file, line, position and
377 * extra parameters.
378 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000379static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000380xmlHTMLError(void *ctx, const char *msg, ...)
381{
382 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
383 xmlParserInputPtr input;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000384 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000385 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000386
387 buffer[0] = 0;
388 input = ctxt->input;
389 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000390 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;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000421 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000422 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000423
424 buffer[0] = 0;
425 input = ctxt->input;
426 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000427 input = ctxt->inputTab[ctxt->inputNr - 2];
428 }
429
430
431 xmlHTMLPrintFileInfo(input);
432
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000433 xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000434 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000435 len = strlen(buffer);
436 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000437 va_end(args);
438 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000439 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000440
441 xmlHTMLPrintFileContext(input);
442 xmlHTMLEncodeSend();
443}
444
445/**
446 * xmlHTMLValidityError:
447 * @ctx: an XML parser context
448 * @msg: the message to display/transmit
449 * @...: extra parameters for the message display
450 *
451 * Display and format an validity error messages, gives file,
452 * line, position and extra parameters.
453 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000454static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000455xmlHTMLValidityError(void *ctx, const char *msg, ...)
456{
457 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
458 xmlParserInputPtr input;
459 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000460 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000461
462 buffer[0] = 0;
463 input = ctxt->input;
464 if ((input->filename == NULL) && (ctxt->inputNr > 1))
465 input = ctxt->inputTab[ctxt->inputNr - 2];
466
467 xmlHTMLPrintFileInfo(input);
468
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000469 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000470 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000471 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000472 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000473 va_end(args);
474 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000475 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000476
477 xmlHTMLPrintFileContext(input);
478 xmlHTMLEncodeSend();
479}
480
481/**
482 * xmlHTMLValidityWarning:
483 * @ctx: an XML parser context
484 * @msg: the message to display/transmit
485 * @...: extra parameters for the message display
486 *
487 * Display and format a validity warning messages, gives file, line,
488 * position and extra parameters.
489 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000490static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000491xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
492{
493 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
494 xmlParserInputPtr input;
495 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000496 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000497
498 buffer[0] = 0;
499 input = ctxt->input;
500 if ((input->filename == NULL) && (ctxt->inputNr > 1))
501 input = ctxt->inputTab[ctxt->inputNr - 2];
502
503 xmlHTMLPrintFileInfo(input);
504
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000505 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000506 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000507 len = strlen(buffer);
508 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000509 va_end(args);
510 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000511 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000512
513 xmlHTMLPrintFileContext(input);
514 xmlHTMLEncodeSend();
515}
516
517/************************************************************************
518 * *
519 * Shell Interface *
520 * *
521 ************************************************************************/
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000522#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000523/**
524 * xmlShellReadline:
525 * @prompt: the prompt value
526 *
527 * Read a string
528 *
529 * Returns a pointer to it or NULL on EOF the caller is expected to
530 * free the returned string.
531 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000532static char *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000533xmlShellReadline(char *prompt) {
534#ifdef HAVE_LIBREADLINE
535 char *line_read;
536
537 /* Get a line from the user. */
538 line_read = readline (prompt);
539
540 /* If the line has any text in it, save it on the history. */
541 if (line_read && *line_read)
542 add_history (line_read);
543
544 return (line_read);
545#else
546 char line_read[501];
Daniel Veillard29e43992001-12-13 22:21:58 +0000547 char *ret;
548 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000549
550 if (prompt != NULL)
551 fprintf(stdout, "%s", prompt);
552 if (!fgets(line_read, 500, stdin))
553 return(NULL);
554 line_read[500] = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000555 len = strlen(line_read);
556 ret = (char *) malloc(len + 1);
557 if (ret != NULL) {
558 memcpy (ret, line_read, len + 1);
559 }
560 return(ret);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000561#endif
562}
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000563#endif /* LIBXML_DEBUG_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000564
565/************************************************************************
566 * *
Daniel Veillard5e873c42000-04-12 13:27:38 +0000567 * I/O Interfaces *
568 * *
569 ************************************************************************/
570
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000571static int myRead(FILE *f, char * buf, int len) {
572 return(fread(buf, 1, len, f));
Daniel Veillard5e873c42000-04-12 13:27:38 +0000573}
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000574static void myClose(FILE *f) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000575 if (f != stdin) {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000576 fclose(f);
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000577 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000578}
579
580/************************************************************************
581 * *
Daniel Veillard7704fb12003-01-03 16:19:51 +0000582 * Stream Test processing *
583 * *
584 ************************************************************************/
Daniel Veillard7704fb12003-01-03 16:19:51 +0000585static void processNode(xmlTextReaderPtr reader) {
Daniel Veillarde59494f2003-01-04 16:35:29 +0000586 xmlChar *name, *value;
Daniel Veillard7704fb12003-01-03 16:19:51 +0000587
Daniel Veillarde59494f2003-01-04 16:35:29 +0000588 name = xmlTextReaderName(reader);
589 if (name == NULL)
590 name = xmlStrdup(BAD_CAST "--");
Daniel Veillard99737f52003-03-22 14:55:50 +0000591
Daniel Veillarde59494f2003-01-04 16:35:29 +0000592 value = xmlTextReaderValue(reader);
Daniel Veillard7704fb12003-01-03 16:19:51 +0000593
Daniel Veillard99737f52003-03-22 14:55:50 +0000594 printf("%d %d %s %d %d",
Daniel Veillarde59494f2003-01-04 16:35:29 +0000595 xmlTextReaderDepth(reader),
596 xmlTextReaderNodeType(reader),
597 name,
Daniel Veillard99737f52003-03-22 14:55:50 +0000598 xmlTextReaderIsEmptyElement(reader),
599 xmlTextReaderHasValue(reader));
Daniel Veillarde59494f2003-01-04 16:35:29 +0000600 xmlFree(name);
601 if (value == NULL)
602 printf("\n");
603 else {
604 printf(" %s\n", value);
605 xmlFree(value);
Daniel Veillard7704fb12003-01-03 16:19:51 +0000606 }
607}
608
609static void streamFile(char *filename) {
610 xmlTextReaderPtr reader;
611 int ret;
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +0000612#ifdef HAVE_SYS_MMAN_H
613 int fd = -1;
614 struct stat info;
615 const char *base = NULL;
616 xmlParserInputBufferPtr input = NULL;
Daniel Veillard7704fb12003-01-03 16:19:51 +0000617
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +0000618 if (memory) {
619 if (stat(filename, &info) < 0)
620 return;
621 if ((fd = open(filename, O_RDONLY)) < 0)
622 return;
623 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
624 if (base == (void *) MAP_FAILED)
625 return;
626
627 input = xmlParserInputBufferCreateMem((char *) base, info.st_size,
628 XML_CHAR_ENCODING_NONE);
629 reader = xmlNewTextReader(input, filename);
630 } else
631#endif
632 reader = xmlNewTextReaderFilename(filename);
633
Daniel Veillard7704fb12003-01-03 16:19:51 +0000634 if (reader != NULL) {
635 if (valid)
636 xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
Daniel Veillardce192eb2003-04-16 15:58:05 +0000637 else
638 xmlTextReaderSetParserProp(reader, XML_PARSER_LOADDTD, 1);
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000639#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +0000640 if (relaxng != NULL) {
Daniel Veillard81514ba2003-09-16 23:17:26 +0000641 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +0000642 startTimer();
643 }
644 ret = xmlTextReaderRelaxNGValidate(reader, relaxng);
645 if (ret < 0) {
646 xmlGenericError(xmlGenericErrorContext,
647 "Relax-NG schema %s failed to compile\n", relaxng);
648 relaxng = NULL;
649 }
Daniel Veillard81514ba2003-09-16 23:17:26 +0000650 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +0000651 endTimer("Compiling the schemas");
652 }
653 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000654#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +0000655
656 /*
657 * Process all nodes in sequence
658 */
Daniel Veillard81514ba2003-09-16 23:17:26 +0000659 if ((timing) && (!repeat)) {
Daniel Veillardce192eb2003-04-16 15:58:05 +0000660 startTimer();
661 }
Daniel Veillard7704fb12003-01-03 16:19:51 +0000662 ret = xmlTextReaderRead(reader);
663 while (ret == 1) {
664 if (debug)
665 processNode(reader);
666 ret = xmlTextReaderRead(reader);
667 }
Daniel Veillard81514ba2003-09-16 23:17:26 +0000668 if ((timing) && (!repeat)) {
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000669#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +0000670 if ((valid) || (relaxng != NULL))
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000671#else
672 if (valid)
673#endif
Daniel Veillardce192eb2003-04-16 15:58:05 +0000674 endTimer("Parsing and validating");
675 else
676 endTimer("Parsing");
677 }
Daniel Veillard7704fb12003-01-03 16:19:51 +0000678
Daniel Veillardf6bad792003-04-11 19:38:54 +0000679 if (valid) {
680 if (xmlTextReaderIsValid(reader) != 1) {
681 xmlGenericError(xmlGenericErrorContext,
682 "Document %s does not validate\n", filename);
683 progresult = 3;
684 }
685 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000686#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf4e55762003-04-15 23:32:22 +0000687 if (relaxng != NULL) {
688 if (xmlTextReaderIsValid(reader) != 1) {
689 printf("%s fails to validate\n", filename);
690 progresult = 3;
691 } else {
692 printf("%s validates\n", filename);
693 }
694 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000695#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +0000696 /*
697 * Done, cleanup and status
698 */
699 xmlFreeTextReader(reader);
700 if (ret != 0) {
701 printf("%s : failed to parse\n", filename);
Daniel Veillardf6bad792003-04-11 19:38:54 +0000702 progresult = 1;
Daniel Veillard7704fb12003-01-03 16:19:51 +0000703 }
704 } else {
705 fprintf(stderr, "Unable to open %s\n", filename);
Daniel Veillardf6bad792003-04-11 19:38:54 +0000706 progresult = 1;
Daniel Veillard7704fb12003-01-03 16:19:51 +0000707 }
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +0000708#ifdef HAVE_SYS_MMAN_H
709 if (memory) {
710 xmlFreeParserInputBuffer(input);
711 munmap((char *) base, info.st_size);
712 close(fd);
713 }
714#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +0000715}
716
717/************************************************************************
718 * *
719 * Tree Test processing *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000720 * *
721 ************************************************************************/
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000722static void parseAndPrintFile(char *filename) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000723 xmlDocPtr doc = NULL, tmp;
724
Daniel Veillard48b2f892001-02-25 16:11:03 +0000725 if ((timing) && (!repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +0000726 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +0000727
728
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000729 if (filename == NULL) {
730 if (generate) {
731 xmlNodePtr n;
732
733 doc = xmlNewDoc(BAD_CAST "1.0");
734 n = xmlNewNode(NULL, BAD_CAST "info");
735 xmlNodeSetContent(n, BAD_CAST "abc");
736 xmlDocSetRootElement(doc, n);
737 }
738 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000739#ifdef LIBXML_HTML_ENABLED
William M. Brack78637da2003-07-31 14:47:38 +0000740 else if ((html) && (push)) {
741 FILE *f;
742
743 f = fopen(filename, "r");
744 if (f != NULL) {
745 int res, size = 3;
746 char chars[4096];
747 htmlParserCtxtPtr ctxt;
748
749 /* if (repeat) */
750 size = 4096;
751 res = fread(chars, 1, 4, f);
752 if (res > 0) {
753 ctxt = htmlCreatePushParserCtxt(NULL, NULL,
754 chars, res, filename, 0);
755 while ((res = fread(chars, 1, size, f)) > 0) {
756 htmlParseChunk(ctxt, chars, res, 0);
757 }
758 htmlParseChunk(ctxt, chars, 0, 1);
759 doc = ctxt->myDoc;
760 htmlFreeParserCtxt(ctxt);
761 }
762 fclose(f);
763 }
764 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000765 else if (html) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000766 doc = htmlParseFile(filename, NULL);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000767 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000768#endif /* LIBXML_HTML_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000769 else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000770 /*
771 * build an XML tree from a string;
772 */
773 if (push) {
774 FILE *f;
775
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000776 /* '-' Usually means stdin -<sven@zen.org> */
777 if ((filename[0] == '-') && (filename[1] == 0)) {
778 f = stdin;
779 } else {
780 f = fopen(filename, "r");
781 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000782 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +0000783 int ret;
Daniel Veillarda880b122003-04-21 21:36:41 +0000784 int res, size = 1024;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000785 char chars[1024];
786 xmlParserCtxtPtr ctxt;
787
Daniel Veillarda880b122003-04-21 21:36:41 +0000788 /* if (repeat) size = 1024; */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000789 res = fread(chars, 1, 4, f);
790 if (res > 0) {
791 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
792 chars, res, filename);
793 while ((res = fread(chars, 1, size, f)) > 0) {
794 xmlParseChunk(ctxt, chars, res, 0);
795 }
796 xmlParseChunk(ctxt, chars, 0, 1);
797 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +0000798 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000799 xmlFreeParserCtxt(ctxt);
Daniel Veillarde715dd22000-08-29 18:29:38 +0000800 if (!ret) {
801 xmlFreeDoc(doc);
802 doc = NULL;
803 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000804 }
805 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000806 } else if (testIO) {
807 int ret;
808 FILE *f;
809
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000810 /* '-' Usually means stdin -<sven@zen.org> */
811 if ((filename[0] == '-') && (filename[1] == 0)) {
812 f = stdin;
813 } else {
814 f = fopen(filename, "r");
815 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000816 if (f != NULL) {
817 xmlParserCtxtPtr ctxt;
818
819 ctxt = xmlCreateIOParserCtxt(NULL, NULL,
820 (xmlInputReadCallback) myRead,
821 (xmlInputCloseCallback) myClose,
822 f, XML_CHAR_ENCODING_NONE);
823 xmlParseDocument(ctxt);
824
825 ret = ctxt->wellFormed;
826 doc = ctxt->myDoc;
827 xmlFreeParserCtxt(ctxt);
828 if (!ret) {
829 xmlFreeDoc(doc);
830 doc = NULL;
831 }
832 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000833 } else if (recovery) {
834 doc = xmlRecoverFile(filename);
835 } else if (htmlout) {
836 int ret;
837 xmlParserCtxtPtr ctxt;
838 xmlSAXHandler silent, *old;
839
840 ctxt = xmlCreateFileParserCtxt(filename);
Daniel Veillard88a172f2000-08-04 18:23:10 +0000841
842 if (ctxt == NULL) {
Daniel Veillardcbaf3992001-12-31 16:16:02 +0000843 /* If xmlCreateFileParserCtxt() return NULL something
Daniel Veillard88a172f2000-08-04 18:23:10 +0000844 strange happened so we don't want to do anything. Do
845 we want to print an error message here?
846 <sven@zen.org> */
Daniel Veillard7ebb1ee2000-08-04 18:24:45 +0000847 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000848 } else {
849 memcpy(&silent, ctxt->sax, sizeof(silent));
850 old = ctxt->sax;
851 silent.error = xmlHTMLError;
852 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000853 silent.warning = xmlHTMLWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000854 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000855 silent.warning = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000856 silent.fatalError = xmlHTMLError;
857 ctxt->sax = &silent;
858 ctxt->vctxt.error = xmlHTMLValidityError;
859 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000860 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000861 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000862 ctxt->vctxt.warning = NULL;
863
Daniel Veillard88a172f2000-08-04 18:23:10 +0000864 xmlParseDocument(ctxt);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000865
Daniel Veillard88a172f2000-08-04 18:23:10 +0000866 ret = ctxt->wellFormed;
867 doc = ctxt->myDoc;
868 ctxt->sax = old;
869 xmlFreeParserCtxt(ctxt);
870 if (!ret) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000871 xmlFreeDoc(doc);
872 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000873 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000874 }
Daniel Veillard46e370e2000-07-21 20:32:03 +0000875#ifdef HAVE_SYS_MMAN_H
876 } else if (memory) {
877 int fd;
878 struct stat info;
879 const char *base;
880 if (stat(filename, &info) < 0)
881 return;
882 if ((fd = open(filename, O_RDONLY)) < 0)
883 return;
884 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillard29579362000-08-14 17:57:48 +0000885 if (base == (void *) MAP_FAILED)
Daniel Veillard46e370e2000-07-21 20:32:03 +0000886 return;
887
888 doc = xmlParseMemory((char *) base, info.st_size);
889 munmap((char *) base, info.st_size);
890#endif
Daniel Veillardea7751d2002-12-20 00:16:24 +0000891 } else if (valid) {
892 int ret;
893 xmlParserCtxtPtr ctxt;
894
895 ctxt = xmlCreateFileParserCtxt(filename);
896
897 if (ctxt == NULL) {
898 doc = NULL;
899 } else {
900 xmlParseDocument(ctxt);
901 if (ctxt->valid == 0)
902 progresult = 4;
903 ret = ctxt->wellFormed;
904 doc = ctxt->myDoc;
905 xmlFreeParserCtxt(ctxt);
906 if (!ret) {
907 xmlFreeDoc(doc);
908 doc = NULL;
909 }
910 }
911 } else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000912 doc = xmlParseFile(filename);
Daniel Veillardea7751d2002-12-20 00:16:24 +0000913 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000914 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000915
Daniel Veillard88a172f2000-08-04 18:23:10 +0000916 /*
917 * If we don't have a document we might as well give up. Do we
918 * want an error message here? <sven@zen.org> */
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000919 if (doc == NULL) {
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000920 progresult = 1;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000921 return;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000922 }
923
Daniel Veillard48b2f892001-02-25 16:11:03 +0000924 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +0000925 endTimer("Parsing");
Daniel Veillard48b2f892001-02-25 16:11:03 +0000926 }
927
Daniel Veillard29e43992001-12-13 22:21:58 +0000928 /*
929 * Remove DOCTYPE nodes
930 */
931 if (dropdtd) {
932 xmlDtdPtr dtd;
933
934 dtd = xmlGetIntSubset(doc);
935 if (dtd != NULL) {
936 xmlUnlinkNode((xmlNodePtr)dtd);
937 xmlFreeDtd(dtd);
938 }
939 }
940
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000941#ifdef LIBXML_XINCLUDE_ENABLED
Daniel Veillard48b2f892001-02-25 16:11:03 +0000942 if (xinclude) {
943 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +0000944 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +0000945 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000946 xmlXIncludeProcess(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000947 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +0000948 endTimer("Xinclude processing");
Daniel Veillard48b2f892001-02-25 16:11:03 +0000949 }
950 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000951#endif
Daniel Veillard88a172f2000-08-04 18:23:10 +0000952
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000953#ifdef LIBXML_DEBUG_ENABLED
954 /*
Daniel Veillardcbaf3992001-12-31 16:16:02 +0000955 * shell interaction
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000956 */
957 if (shell)
958 xmlShell(doc, filename, xmlShellReadline, stdout);
959#endif
960
961 /*
962 * test intermediate copy if needed.
963 */
964 if (copy) {
965 tmp = doc;
966 doc = xmlCopyDoc(doc, 1);
967 xmlFreeDoc(tmp);
968 }
969
970 if ((insert) && (!html)) {
971 const xmlChar* list[256];
972 int nb, i;
973 xmlNodePtr node;
974
975 if (doc->children != NULL) {
976 node = doc->children;
977 while ((node != NULL) && (node->last == NULL)) node = node->next;
978 if (node != NULL) {
979 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
980 if (nb < 0) {
981 printf("could not get valid list of elements\n");
982 } else if (nb == 0) {
MDT 2001 John Fleckbbb9e432001-09-24 03:08:43 +0000983 printf("No element can be inserted under root\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000984 } else {
MDT 2001 John Fleckbbb9e432001-09-24 03:08:43 +0000985 printf("%d element types can be inserted under root:\n",
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000986 nb);
987 for (i = 0;i < nb;i++) {
Daniel Veillard8a1b1852003-01-05 22:37:17 +0000988 printf("%s\n", (char *) list[i]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000989 }
990 }
991 }
992 }
993 }else if (noout == 0) {
994 /*
995 * print it.
996 */
997#ifdef LIBXML_DEBUG_ENABLED
998 if (!debug) {
999#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00001000 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001001 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001002 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +00001003#ifdef HAVE_SYS_MMAN_H
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001004 if (memory) {
1005 xmlChar *result;
1006 int len;
1007
1008 if (encoding != NULL) {
Daniel Veillardd536f702001-11-08 17:32:47 +00001009 if ( format ) {
1010 xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
1011 } else {
1012 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
1013 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001014 } else {
Daniel Veillard90493a92001-08-14 14:12:47 +00001015 if (format)
1016 xmlDocDumpFormatMemory(doc, &result, &len, 1);
1017 else
1018 xmlDocDumpMemory(doc, &result, &len);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001019 }
1020 if (result == NULL) {
1021 fprintf(stderr, "Failed to save\n");
1022 } else {
1023 write(1, result, len);
1024 xmlFree(result);
1025 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +00001026 } else
1027#endif /* HAVE_SYS_MMAN_H */
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001028 if (compress) {
1029 xmlSaveFile(output ? output : "-", doc);
1030 }
Daniel Veillardd536f702001-11-08 17:32:47 +00001031 else if (encoding != NULL) {
1032 if ( format ) {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001033 xmlSaveFormatFileEnc(output ? output : "-", doc, encoding, 1);
1034 }
Daniel Veillardd536f702001-11-08 17:32:47 +00001035 else {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001036 xmlSaveFileEnc(output ? output : "-", doc, encoding);
Daniel Veillardd536f702001-11-08 17:32:47 +00001037 }
1038 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001039 else if (format) {
1040 xmlSaveFormatFile(output ? output : "-", doc, 1);
1041 }
1042 else {
1043 FILE *out;
1044 if (output == NULL)
1045 out = stdout;
1046 else {
1047 out = fopen(output,"wb");
1048 }
1049 xmlDocDump(out, doc);
1050
1051 if (output)
1052 fclose(out);
1053 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001054 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001055 endTimer("Saving");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001056 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001057#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001058 } else {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001059 FILE *out;
1060 if (output == NULL)
1061 out = stdout;
1062 else {
1063 out = fopen(output,"wb");
1064 }
1065 xmlDebugDumpDocument(out, doc);
1066
1067 if (output)
1068 fclose(out);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001069 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001070#endif
1071 }
1072
1073 /*
1074 * A posteriori validation test
1075 */
Daniel Veillard66f68e72003-08-18 16:39:51 +00001076 if ((dtdvalid != NULL) || (dtdvalidfpi != NULL)) {
Daniel Veillardcd429612000-10-11 15:57:05 +00001077 xmlDtdPtr dtd;
1078
Daniel Veillard48b2f892001-02-25 16:11:03 +00001079 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001080 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001081 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00001082 if (dtdvalid != NULL)
1083 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
1084 else
1085 dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL);
Daniel Veillard48b2f892001-02-25 16:11:03 +00001086 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001087 endTimer("Parsing DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001088 }
Daniel Veillardcd429612000-10-11 15:57:05 +00001089 if (dtd == NULL) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00001090 if (dtdvalid != NULL)
1091 xmlGenericError(xmlGenericErrorContext,
1092 "Could not parse DTD %s\n", dtdvalid);
1093 else
1094 xmlGenericError(xmlGenericErrorContext,
1095 "Could not parse DTD %s\n", dtdvalidfpi);
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001096 progresult = 2;
Daniel Veillardcd429612000-10-11 15:57:05 +00001097 } else {
Daniel Veillarda37aab82003-06-09 09:10:36 +00001098 xmlValidCtxtPtr cvp;
1099
1100 if ((cvp = xmlNewValidCtxt()) == NULL) {
1101 xmlGenericError(xmlGenericErrorContext,
1102 "Couldn't allocate validation context\n");
1103 exit(-1);
1104 }
1105 cvp->userData = (void *) stderr;
1106 cvp->error = (xmlValidityErrorFunc) fprintf;
1107 cvp->warning = (xmlValidityWarningFunc) fprintf;
1108
Daniel Veillard48b2f892001-02-25 16:11:03 +00001109 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001110 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001111 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00001112 if (!xmlValidateDtd(cvp, doc, dtd)) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00001113 if (dtdvalid != NULL)
1114 xmlGenericError(xmlGenericErrorContext,
1115 "Document %s does not validate against %s\n",
1116 filename, dtdvalid);
1117 else
1118 xmlGenericError(xmlGenericErrorContext,
1119 "Document %s does not validate against %s\n",
1120 filename, dtdvalidfpi);
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001121 progresult = 3;
Daniel Veillardcd429612000-10-11 15:57:05 +00001122 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001123 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001124 endTimer("Validating against DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001125 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00001126 xmlFreeValidCtxt(cvp);
Daniel Veillardcd429612000-10-11 15:57:05 +00001127 xmlFreeDtd(dtd);
1128 }
1129 } else if (postvalid) {
Daniel Veillarda37aab82003-06-09 09:10:36 +00001130 xmlValidCtxtPtr cvp;
1131
1132 if ((cvp = xmlNewValidCtxt()) == NULL) {
1133 xmlGenericError(xmlGenericErrorContext,
1134 "Couldn't allocate validation context\n");
1135 exit(-1);
1136 }
1137
Daniel Veillard48b2f892001-02-25 16:11:03 +00001138 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001139 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001140 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00001141 cvp->userData = (void *) stderr;
1142 cvp->error = (xmlValidityErrorFunc) fprintf;
1143 cvp->warning = (xmlValidityWarningFunc) fprintf;
1144 if (!xmlValidateDocument(cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001145 xmlGenericError(xmlGenericErrorContext,
1146 "Document %s does not validate\n", filename);
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001147 progresult = 3;
Daniel Veillardcd429612000-10-11 15:57:05 +00001148 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001149 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001150 endTimer("Validating");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001151 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00001152 xmlFreeValidCtxt(cvp);
Daniel Veillard71531f32003-02-05 13:19:53 +00001153#ifdef LIBXML_SCHEMAS_ENABLED
1154 } else if (relaxngschemas != NULL) {
1155 xmlRelaxNGValidCtxtPtr ctxt;
1156 int ret;
1157
Daniel Veillard42f12e92003-03-07 18:32:59 +00001158 if ((timing) && (!repeat)) {
1159 startTimer();
1160 }
1161
Daniel Veillard71531f32003-02-05 13:19:53 +00001162 ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
1163 xmlRelaxNGSetValidErrors(ctxt,
1164 (xmlRelaxNGValidityErrorFunc) fprintf,
1165 (xmlRelaxNGValidityWarningFunc) fprintf,
1166 stderr);
1167 ret = xmlRelaxNGValidateDoc(ctxt, doc);
1168 if (ret == 0) {
1169 printf("%s validates\n", filename);
1170 } else if (ret > 0) {
1171 printf("%s fails to validate\n", filename);
1172 } else {
1173 printf("%s validation generated an internal error\n",
1174 filename);
1175 }
1176 xmlRelaxNGFreeValidCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00001177 if ((timing) && (!repeat)) {
1178 endTimer("Validating");
1179 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001180 } else if (wxschemas != NULL) {
1181 xmlSchemaValidCtxtPtr ctxt;
1182 int ret;
1183
1184 if ((timing) && (!repeat)) {
1185 startTimer();
1186 }
1187
1188 ctxt = xmlSchemaNewValidCtxt(wxschemas);
1189 xmlSchemaSetValidErrors(ctxt,
1190 (xmlSchemaValidityErrorFunc) fprintf,
1191 (xmlSchemaValidityWarningFunc) fprintf,
1192 stderr);
1193 ret = xmlSchemaValidateDoc(ctxt, doc);
1194 if (ret == 0) {
1195 printf("%s validates\n", filename);
1196 } else if (ret > 0) {
1197 printf("%s fails to validate\n", filename);
1198 } else {
1199 printf("%s validation generated an internal error\n",
1200 filename);
1201 }
1202 xmlSchemaFreeValidCtxt(ctxt);
1203 if ((timing) && (!repeat)) {
1204 endTimer("Validating");
1205 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001206#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001207 }
1208
1209#ifdef LIBXML_DEBUG_ENABLED
1210 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001211 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001212#endif
1213
1214 /*
1215 * free it.
1216 */
Daniel Veillard48b2f892001-02-25 16:11:03 +00001217 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001218 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001219 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001220 xmlFreeDoc(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +00001221 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001222 endTimer("Freeing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001223 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001224}
1225
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001226/************************************************************************
1227 * *
1228 * Usage and Main *
1229 * *
1230 ************************************************************************/
1231
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00001232static void showVersion(const char *name) {
1233 fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
1234 fprintf(stderr, " compiled with: ");
1235#ifdef LIBXML_FTP_ENABLED
1236 fprintf(stderr, "FTP ");
1237#endif
1238#ifdef LIBXML_HTTP_ENABLED
1239 fprintf(stderr, "HTTP ");
1240#endif
1241#ifdef LIBXML_HTML_ENABLED
1242 fprintf(stderr, "HTML ");
1243#endif
1244#ifdef LIBXML_C14N_ENABLED
1245 fprintf(stderr, "C14N ");
1246#endif
1247#ifdef LIBXML_CATALOG_ENABLED
1248 fprintf(stderr, "Catalog ");
1249#endif
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00001250#ifdef LIBXML_XPATH_ENABLED
1251 fprintf(stderr, "XPath ");
1252#endif
1253#ifdef LIBXML_XPTR_ENABLED
1254 fprintf(stderr, "XPointer ");
1255#endif
1256#ifdef LIBXML_XINCLUDE_ENABLED
1257 fprintf(stderr, "XInclude ");
1258#endif
1259#ifdef LIBXML_ICONV_ENABLED
1260 fprintf(stderr, "Iconv ");
1261#endif
1262#ifdef DEBUG_MEMORY_LOCATION
1263 fprintf(stderr, "MemDebug ");
1264#endif
1265#ifdef LIBXML_UNICODE_ENABLED
1266 fprintf(stderr, "Unicode ");
1267#endif
1268#ifdef LIBXML_REGEXP_ENABLED
1269 fprintf(stderr, "Regexps ");
1270#endif
1271#ifdef LIBXML_AUTOMATA_ENABLED
1272 fprintf(stderr, "Automata ");
1273#endif
1274#ifdef LIBXML_SCHEMAS_ENABLED
1275 fprintf(stderr, "Schemas ");
1276#endif
1277 fprintf(stderr, "\n");
1278}
1279
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001280static void usage(const char *name) {
1281 printf("Usage : %s [options] XMLfiles ...\n", name);
1282 printf("\tParse the XML files and output the result of the parsing\n");
1283 printf("\t--version : display the version of the XML library used\n");
1284#ifdef LIBXML_DEBUG_ENABLED
1285 printf("\t--debug : dump a debug tree of the in-memory document\n");
1286 printf("\t--shell : run a navigating shell\n");
1287 printf("\t--debugent : debug the entities defined in the document\n");
Daniel Veillard8326e732003-01-07 00:19:07 +00001288#else
1289 printf("\t--debug : dump the nodes content when using --stream\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001290#endif
1291 printf("\t--copy : used to test the internal copy implementation\n");
1292 printf("\t--recover : output what was parsable on broken XML documents\n");
1293 printf("\t--noent : substitute entity references by their value\n");
1294 printf("\t--noout : don't output the result tree\n");
Daniel Veillarde8b09e42003-05-13 22:14:13 +00001295 printf("\t--nonet : refuse to fetch DTDs or entities over network\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001296 printf("\t--htmlout : output results as HTML\n");
Daniel Veillard05c13a22001-09-09 08:38:09 +00001297 printf("\t--nowrap : do not put HTML doc wrapper\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001298 printf("\t--valid : validate the document in addition to std well-formed check\n");
1299 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
1300 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
Daniel Veillard66f68e72003-08-18 16:39:51 +00001301 printf("\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001302 printf("\t--timing : print some timings\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001303 printf("\t--output file or -o file: save to a given file\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001304 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
1305 printf("\t--insert : ad-hoc test for valid insertions\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001306#ifdef HAVE_ZLIB_H
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001307 printf("\t--compress : turn on gzip compression of output\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001308#endif
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001309#ifdef LIBXML_HTML_ENABLED
1310 printf("\t--html : use the HTML parser\n");
1311#endif
1312 printf("\t--push : use the push mode of the parser\n");
1313#ifdef HAVE_SYS_MMAN_H
1314 printf("\t--memory : parse from memory\n");
1315#endif
1316 printf("\t--nowarning : do not emit warnings from parser/validator\n");
1317 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
Daniel Veillard90493a92001-08-14 14:12:47 +00001318 printf("\t--format : reformat/reindent the input\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001319 printf("\t--testIO : test user I/O support\n");
1320 printf("\t--encode encoding : output in the given encoding\n");
1321#ifdef LIBXML_CATALOG_ENABLED
Daniel Veillardbd9b0e82001-11-26 10:32:08 +00001322 printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
1323 printf("\t otherwise XML Catalogs starting from \n");
Daniel Veillard3be27512003-01-26 19:49:04 +00001324 printf("\t " XML_XML_DEFAULT_CATALOG " are activated by default\n");
Daniel Veillard05c13a22001-09-09 08:38:09 +00001325 printf("\t--nocatalogs: deactivate all catalogs\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001326#endif
1327 printf("\t--auto : generate a small doc on the fly\n");
1328#ifdef LIBXML_XINCLUDE_ENABLED
1329 printf("\t--xinclude : do XInclude processing\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001330#endif
Daniel Veillardcbaf3992001-12-31 16:16:02 +00001331 printf("\t--loaddtd : fetch external DTD\n");
Daniel Veillard48da9102001-08-07 01:10:10 +00001332 printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
Daniel Veillard29e43992001-12-13 22:21:58 +00001333 printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
Daniel Veillard7704fb12003-01-03 16:19:51 +00001334 printf("\t--stream : use the streaming interface to process very large files\n");
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001335 printf("\t--chkregister : verify the node registration code\n");
Daniel Veillardef4d3bc2003-02-07 12:38:22 +00001336#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard71531f32003-02-05 13:19:53 +00001337 printf("\t--relaxng schema : do RelaxNG validation against the schema\n");
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001338 printf("\t--schema schema : do validation against the WXS schema\n");
Daniel Veillard71531f32003-02-05 13:19:53 +00001339#endif
Daniel Veillarda42f25f2002-01-25 14:15:40 +00001340 printf("\nLibxml project home page: http://xmlsoft.org/\n");
1341 printf("To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001342}
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001343
1344static void registerNode(xmlNodePtr node)
1345{
1346 node->_private = malloc(sizeof(long));
1347 *(long*)node->_private = (long) 0x81726354;
1348}
1349
1350static void deregisterNode(xmlNodePtr node)
1351{
1352 assert(node->_private != NULL);
1353 assert(*(long*)node->_private == (long) 0x81726354);
1354 free(node->_private);
1355}
1356
Daniel Veillard4a6845d2001-01-03 13:32:39 +00001357int
1358main(int argc, char **argv) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00001359 int i, acount;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001360 int files = 0;
Daniel Veillard845cce42002-01-09 11:51:37 +00001361 int version = 0;
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00001362 const char* indent;
1363
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001364 if (argc <= 1) {
1365 usage(argv[0]);
1366 return(1);
1367 }
Daniel Veillardbe803962000-06-28 23:40:59 +00001368 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001369 for (i = 1; i < argc ; i++) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001370 if (!strcmp(argv[i], "-"))
1371 break;
1372
1373 if (argv[i][0] != '-')
1374 continue;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001375 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
1376 debug++;
Daniel Veillard56ada1d2003-01-07 11:17:25 +00001377 else
1378#ifdef LIBXML_DEBUG_ENABLED
1379 if ((!strcmp(argv[i], "-shell")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001380 (!strcmp(argv[i], "--shell"))) {
1381 shell++;
1382 noout = 1;
1383 } else
1384#endif
1385 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
1386 copy++;
1387 else if ((!strcmp(argv[i], "-recover")) ||
1388 (!strcmp(argv[i], "--recover")))
1389 recovery++;
1390 else if ((!strcmp(argv[i], "-noent")) ||
1391 (!strcmp(argv[i], "--noent")))
1392 noent++;
Daniel Veillard4ec885a2001-06-17 10:31:07 +00001393 else if ((!strcmp(argv[i], "-version")) ||
Daniel Veillard845cce42002-01-09 11:51:37 +00001394 (!strcmp(argv[i], "--version"))) {
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00001395 showVersion(argv[0]);
Daniel Veillard845cce42002-01-09 11:51:37 +00001396 version = 1;
1397 } else if ((!strcmp(argv[i], "-noout")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001398 (!strcmp(argv[i], "--noout")))
1399 noout++;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001400 else if ((!strcmp(argv[i], "-o")) ||
1401 (!strcmp(argv[i], "-output")) ||
1402 (!strcmp(argv[i], "--output"))) {
1403 i++;
Daniel Veillard6e4f1c02002-04-09 09:55:20 +00001404 output = argv[i];
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001405 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001406 else if ((!strcmp(argv[i], "-htmlout")) ||
1407 (!strcmp(argv[i], "--htmlout")))
1408 htmlout++;
1409#ifdef LIBXML_HTML_ENABLED
1410 else if ((!strcmp(argv[i], "-html")) ||
1411 (!strcmp(argv[i], "--html"))) {
1412 html++;
1413 }
1414#endif /* LIBXML_HTML_ENABLED */
1415 else if ((!strcmp(argv[i], "-nowrap")) ||
1416 (!strcmp(argv[i], "--nowrap")))
1417 nowrap++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001418 else if ((!strcmp(argv[i], "-loaddtd")) ||
1419 (!strcmp(argv[i], "--loaddtd")))
1420 loaddtd++;
Daniel Veillard48da9102001-08-07 01:10:10 +00001421 else if ((!strcmp(argv[i], "-dtdattr")) ||
1422 (!strcmp(argv[i], "--dtdattr"))) {
1423 loaddtd++;
1424 dtdattrs++;
1425 } else if ((!strcmp(argv[i], "-valid")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001426 (!strcmp(argv[i], "--valid")))
1427 valid++;
1428 else if ((!strcmp(argv[i], "-postvalid")) ||
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001429 (!strcmp(argv[i], "--postvalid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001430 postvalid++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001431 loaddtd++;
1432 } else if ((!strcmp(argv[i], "-dtdvalid")) ||
Daniel Veillardcd429612000-10-11 15:57:05 +00001433 (!strcmp(argv[i], "--dtdvalid"))) {
1434 i++;
1435 dtdvalid = argv[i];
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001436 loaddtd++;
Daniel Veillard66f68e72003-08-18 16:39:51 +00001437 } else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
1438 (!strcmp(argv[i], "--dtdvalidfpi"))) {
1439 i++;
1440 dtdvalidfpi = argv[i];
1441 loaddtd++;
Daniel Veillardcd429612000-10-11 15:57:05 +00001442 }
Daniel Veillard29e43992001-12-13 22:21:58 +00001443 else if ((!strcmp(argv[i], "-dropdtd")) ||
1444 (!strcmp(argv[i], "--dropdtd")))
1445 dropdtd++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001446 else if ((!strcmp(argv[i], "-insert")) ||
1447 (!strcmp(argv[i], "--insert")))
1448 insert++;
Daniel Veillard48b2f892001-02-25 16:11:03 +00001449 else if ((!strcmp(argv[i], "-timing")) ||
1450 (!strcmp(argv[i], "--timing")))
1451 timing++;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001452 else if ((!strcmp(argv[i], "-auto")) ||
1453 (!strcmp(argv[i], "--auto")))
1454 generate++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001455 else if ((!strcmp(argv[i], "-repeat")) ||
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001456 (!strcmp(argv[i], "--repeat"))) {
1457 if (repeat)
1458 repeat *= 10;
1459 else
1460 repeat = 100;
1461 } else if ((!strcmp(argv[i], "-push")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001462 (!strcmp(argv[i], "--push")))
1463 push++;
Daniel Veillard46e370e2000-07-21 20:32:03 +00001464#ifdef HAVE_SYS_MMAN_H
1465 else if ((!strcmp(argv[i], "-memory")) ||
1466 (!strcmp(argv[i], "--memory")))
1467 memory++;
1468#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +00001469 else if ((!strcmp(argv[i], "-testIO")) ||
1470 (!strcmp(argv[i], "--testIO")))
1471 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00001472#ifdef LIBXML_XINCLUDE_ENABLED
1473 else if ((!strcmp(argv[i], "-xinclude")) ||
1474 (!strcmp(argv[i], "--xinclude")))
1475 xinclude++;
1476#endif
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001477#ifdef HAVE_ZLIB_H
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001478 else if ((!strcmp(argv[i], "-compress")) ||
1479 (!strcmp(argv[i], "--compress"))) {
1480 compress++;
1481 xmlSetCompressMode(9);
1482 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001483#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001484 else if ((!strcmp(argv[i], "-nowarning")) ||
1485 (!strcmp(argv[i], "--nowarning"))) {
1486 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001487 xmlPedanticParserDefault(0);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001488 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001489 else if ((!strcmp(argv[i], "-pedantic")) ||
1490 (!strcmp(argv[i], "--pedantic"))) {
1491 xmlGetWarningsDefaultValue = 1;
1492 xmlPedanticParserDefault(1);
1493 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00001494#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001495 else if ((!strcmp(argv[i], "-debugent")) ||
1496 (!strcmp(argv[i], "--debugent"))) {
1497 debugent++;
1498 xmlParserDebugEntities = 1;
1499 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00001500#endif
Daniel Veillard81418e32001-05-22 15:08:55 +00001501#ifdef LIBXML_CATALOG_ENABLED
1502 else if ((!strcmp(argv[i], "-catalogs")) ||
1503 (!strcmp(argv[i], "--catalogs"))) {
Daniel Veillarde2940dd2001-08-22 00:06:49 +00001504 catalogs++;
1505 } else if ((!strcmp(argv[i], "-nocatalogs")) ||
1506 (!strcmp(argv[i], "--nocatalogs"))) {
1507 nocatalogs++;
Daniel Veillard81418e32001-05-22 15:08:55 +00001508 }
1509#endif
Daniel Veillardbe803962000-06-28 23:40:59 +00001510 else if ((!strcmp(argv[i], "-encode")) ||
1511 (!strcmp(argv[i], "--encode"))) {
1512 i++;
1513 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001514 /*
1515 * OK it's for testing purposes
1516 */
1517 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +00001518 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001519 else if ((!strcmp(argv[i], "-noblanks")) ||
1520 (!strcmp(argv[i], "--noblanks"))) {
1521 noblanks++;
1522 xmlKeepBlanksDefault(0);
Daniel Veillard90493a92001-08-14 14:12:47 +00001523 }
1524 else if ((!strcmp(argv[i], "-format")) ||
1525 (!strcmp(argv[i], "--format"))) {
1526 noblanks++;
1527 format++;
1528 xmlKeepBlanksDefault(0);
Daniel Veillard7704fb12003-01-03 16:19:51 +00001529 }
1530 else if ((!strcmp(argv[i], "-stream")) ||
1531 (!strcmp(argv[i], "--stream"))) {
1532 stream++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001533 }
Daniel Veillard07cb8222003-09-10 10:51:05 +00001534 else if ((!strcmp(argv[i], "-sax1")) ||
1535 (!strcmp(argv[i], "--sax1"))) {
1536 sax1++;
1537 }
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001538 else if ((!strcmp(argv[i], "-chkregister")) ||
1539 (!strcmp(argv[i], "--chkregister"))) {
1540 chkregister++;
Daniel Veillard71531f32003-02-05 13:19:53 +00001541#ifdef LIBXML_SCHEMAS_ENABLED
1542 } else if ((!strcmp(argv[i], "-relaxng")) ||
1543 (!strcmp(argv[i], "--relaxng"))) {
1544 i++;
1545 relaxng = argv[i];
1546 noent++;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001547 } else if ((!strcmp(argv[i], "-schema")) ||
1548 (!strcmp(argv[i], "--schema"))) {
1549 i++;
1550 schema = argv[i];
1551 noent++;
Daniel Veillard71531f32003-02-05 13:19:53 +00001552#endif
Daniel Veillarde8b09e42003-05-13 22:14:13 +00001553 } else if ((!strcmp(argv[i], "-nonet")) ||
1554 (!strcmp(argv[i], "--nonet"))) {
1555 xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001556 } else {
1557 fprintf(stderr, "Unknown option %s\n", argv[i]);
1558 usage(argv[0]);
1559 return(1);
1560 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001561 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00001562
1563#ifdef LIBXML_CATALOG_ENABLED
1564 if (nocatalogs == 0) {
1565 if (catalogs) {
1566 const char *catal;
1567
1568 catal = getenv("SGML_CATALOG_FILES");
Daniel Veillard6c5f9d12001-08-25 13:33:14 +00001569 if (catal != NULL) {
1570 xmlLoadCatalogs(catal);
1571 } else {
1572 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
1573 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00001574 }
1575 }
1576#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001577
Daniel Veillard07cb8222003-09-10 10:51:05 +00001578 if (sax1)
1579 xmlSAXDefaultVersion(1);
1580 else
1581 xmlSAXDefaultVersion(2);
1582
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001583 if (chkregister) {
1584 xmlRegisterNodeDefault(registerNode);
1585 xmlDeregisterNodeDefault(deregisterNode);
1586 }
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00001587
1588 indent = getenv("XMLLINT_INDENT");
1589 if(indent != NULL) {
1590 xmlTreeIndentString = indent;
1591 }
1592
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001593
Daniel Veillardd9bad132001-07-23 19:39:43 +00001594 xmlLineNumbersDefault(1);
Daniel Veillard48da9102001-08-07 01:10:10 +00001595 if (loaddtd != 0)
1596 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
1597 if (dtdattrs)
1598 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001599 if (noent != 0) xmlSubstituteEntitiesDefault(1);
1600 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
1601 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001602 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001603 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001604 xmlGenericError(xmlGenericErrorContext,
1605 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
1606 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001607 "<html><head><title>%s output</title></head>\n",
1608 argv[0]);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001609 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001610 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
1611 argv[0]);
1612 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001613
1614#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +00001615 if ((relaxng != NULL) && (stream == 0)) {
Daniel Veillard71531f32003-02-05 13:19:53 +00001616 xmlRelaxNGParserCtxtPtr ctxt;
1617
Daniel Veillardce192eb2003-04-16 15:58:05 +00001618 /* forces loading the DTDs */
1619 xmlLoadExtDtdDefaultValue |= 1;
Daniel Veillard42f12e92003-03-07 18:32:59 +00001620 if (timing) {
1621 startTimer();
1622 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001623 ctxt = xmlRelaxNGNewParserCtxt(relaxng);
1624 xmlRelaxNGSetParserErrors(ctxt,
1625 (xmlRelaxNGValidityErrorFunc) fprintf,
1626 (xmlRelaxNGValidityWarningFunc) fprintf,
1627 stderr);
1628 relaxngschemas = xmlRelaxNGParse(ctxt);
Daniel Veillardce192eb2003-04-16 15:58:05 +00001629 if (relaxngschemas == NULL) {
1630 xmlGenericError(xmlGenericErrorContext,
1631 "Relax-NG schema %s failed to compile\n", relaxng);
1632 relaxng = NULL;
1633 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001634 xmlRelaxNGFreeParserCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00001635 if (timing) {
1636 endTimer("Compiling the schemas");
1637 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001638 } else if ((schema != NULL) && (stream == 0)) {
1639 xmlSchemaParserCtxtPtr ctxt;
1640
1641 if (timing) {
1642 startTimer();
1643 }
1644 ctxt = xmlSchemaNewParserCtxt(schema);
1645 xmlSchemaSetParserErrors(ctxt,
1646 (xmlSchemaValidityErrorFunc) fprintf,
1647 (xmlSchemaValidityWarningFunc) fprintf,
1648 stderr);
1649 wxschemas = xmlSchemaParse(ctxt);
1650 if (wxschemas == NULL) {
1651 xmlGenericError(xmlGenericErrorContext,
1652 "WXS schema %s failed to compile\n", schema);
1653 schema = NULL;
1654 }
1655 xmlSchemaFreeParserCtxt(ctxt);
1656 if (timing) {
1657 endTimer("Compiling the schemas");
1658 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001659 }
1660#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001661 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +00001662 if ((!strcmp(argv[i], "-encode")) ||
1663 (!strcmp(argv[i], "--encode"))) {
1664 i++;
1665 continue;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001666 } else if ((!strcmp(argv[i], "-o")) ||
1667 (!strcmp(argv[i], "-output")) ||
1668 (!strcmp(argv[i], "--output"))) {
1669 i++;
1670 continue;
Daniel Veillardbe803962000-06-28 23:40:59 +00001671 }
Daniel Veillardcd429612000-10-11 15:57:05 +00001672 if ((!strcmp(argv[i], "-dtdvalid")) ||
1673 (!strcmp(argv[i], "--dtdvalid"))) {
1674 i++;
1675 continue;
1676 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00001677 if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
1678 (!strcmp(argv[i], "--dtdvalidfpi"))) {
1679 i++;
1680 continue;
1681 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001682 if ((!strcmp(argv[i], "-relaxng")) ||
1683 (!strcmp(argv[i], "--relaxng"))) {
1684 i++;
1685 continue;
1686 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001687 if ((!strcmp(argv[i], "-schema")) ||
1688 (!strcmp(argv[i], "--schema"))) {
1689 i++;
1690 continue;
1691 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001692 if ((timing) && (repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00001693 startTimer();
Daniel Veillardcbaf3992001-12-31 16:16:02 +00001694 /* Remember file names. "-" means stdin. <sven@zen.org> */
Daniel Veillard4a6845d2001-01-03 13:32:39 +00001695 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001696 if (repeat) {
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001697 for (acount = 0;acount < repeat;acount++)
Daniel Veillard7704fb12003-01-03 16:19:51 +00001698 if (stream != 0)
1699 streamFile(argv[i]);
1700 else
1701 parseAndPrintFile(argv[i]);
1702 } else {
1703 if (stream != 0)
1704 streamFile(argv[i]);
1705 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001706 parseAndPrintFile(argv[i]);
Daniel Veillard7704fb12003-01-03 16:19:51 +00001707 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001708 files ++;
Daniel Veillarda7866932001-12-04 13:14:44 +00001709 if ((timing) && (repeat)) {
Daniel Veillard8d8bf2c2003-09-17 19:36:25 +00001710 endTimer("%d iterations", repeat);
Daniel Veillarda7866932001-12-04 13:14:44 +00001711 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001712 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001713 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001714 if (generate)
1715 parseAndPrintFile(NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001716 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001717 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001718 }
Daniel Veillard845cce42002-01-09 11:51:37 +00001719 if ((files == 0) && (!generate) && (version == 0)) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001720 usage(argv[0]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001721 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001722#ifdef LIBXML_SCHEMAS_ENABLED
1723 if (relaxngschemas != NULL)
1724 xmlRelaxNGFree(relaxngschemas);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001725 if (wxschemas != NULL)
1726 xmlSchemaFree(wxschemas);
Daniel Veillard71531f32003-02-05 13:19:53 +00001727 xmlRelaxNGCleanupTypes();
1728#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001729 xmlCleanupParser();
1730 xmlMemoryDump();
1731
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001732 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001733}
Daniel Veillard88a172f2000-08-04 18:23:10 +00001734