blob: ccf4ae056ce3d9f2c193d8ecb6cdfb90659be5cd [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 Veillard2d90de42001-04-16 17:46:18 +000016#ifdef _MSC_VER
17#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 Veillard89cad532001-10-22 09:46:13 +000086#ifdef LIBXML_DOCB_ENABLED
87#include <libxml/DOCBparser.h>
88#endif
Daniel Veillard3c01b1d2001-10-17 15:58:35 +000089#include <libxml/globals.h>
Daniel Veillard7704fb12003-01-03 16:19:51 +000090#include <libxml/xmlreader.h>
Daniel Veillard71531f32003-02-05 13:19:53 +000091#ifdef LIBXML_SCHEMAS_ENABLED
92#include <libxml/relaxng.h>
Daniel Veillard75bb3bb2003-05-12 15:25:56 +000093#include <libxml/xmlschemas.h>
Daniel Veillard71531f32003-02-05 13:19:53 +000094#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +000095
Daniel Veillard3be27512003-01-26 19:49:04 +000096#ifndef XML_XML_DEFAULT_CATALOG
97#define XML_XML_DEFAULT_CATALOG "file:///etc/xml/catalog"
98#endif
99
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000100#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000101static int shell = 0;
102static int debugent = 0;
103#endif
Daniel Veillard8326e732003-01-07 00:19:07 +0000104static int debug = 0;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000105static int copy = 0;
106static int recovery = 0;
107static int noent = 0;
108static int noout = 0;
109static int nowrap = 0;
110static int valid = 0;
111static int postvalid = 0;
Daniel Veillardcd429612000-10-11 15:57:05 +0000112static char * dtdvalid = NULL;
Daniel Veillard66f68e72003-08-18 16:39:51 +0000113static char * dtdvalidfpi = NULL;
Daniel Veillard71531f32003-02-05 13:19:53 +0000114#ifdef LIBXML_SCHEMAS_ENABLED
115static char * relaxng = NULL;
116static xmlRelaxNGPtr relaxngschemas = NULL;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +0000117static char * schema = NULL;
118static xmlSchemaPtr wxschemas = NULL;
Daniel Veillard71531f32003-02-05 13:19:53 +0000119#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000120static int repeat = 0;
121static int insert = 0;
122static int compress = 0;
Daniel Veillard89cad532001-10-22 09:46:13 +0000123#ifdef LIBXML_DOCB_ENABLED
124static int sgml = 0;
125#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000126static int html = 0;
127static int htmlout = 0;
128static int push = 0;
Daniel Veillard46e370e2000-07-21 20:32:03 +0000129#ifdef HAVE_SYS_MMAN_H
130static int memory = 0;
131#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000132static int noblanks = 0;
Daniel Veillard90493a92001-08-14 14:12:47 +0000133static int format = 0;
Daniel Veillard5e873c42000-04-12 13:27:38 +0000134static int testIO = 0;
Daniel Veillardbe803962000-06-28 23:40:59 +0000135static char *encoding = NULL;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000136#ifdef LIBXML_XINCLUDE_ENABLED
137static int xinclude = 0;
138#endif
Daniel Veillard48da9102001-08-07 01:10:10 +0000139static int dtdattrs = 0;
Daniel Veillard10ea86c2001-06-20 13:55:33 +0000140static int loaddtd = 0;
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000141static int progresult = 0;
Daniel Veillard48b2f892001-02-25 16:11:03 +0000142static int timing = 0;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000143static int generate = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000144static int dropdtd = 0;
Daniel Veillarde2940dd2001-08-22 00:06:49 +0000145#ifdef LIBXML_CATALOG_ENABLED
146static int catalogs = 0;
147static int nocatalogs = 0;
148#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +0000149static int stream = 0;
Daniel Veillard8a1b1852003-01-05 22:37:17 +0000150static int chkregister = 0;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +0000151static const char *output = NULL;
152
Daniel Veillard01db67c2001-12-18 07:09:59 +0000153/*
154 * Internal timing routines to remove the necessity to have unix-specific
155 * function calls
156 */
157
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000158#ifndef HAVE_GETTIMEOFDAY
159#ifdef HAVE_SYS_TIMEB_H
160#ifdef HAVE_SYS_TIME_H
161#ifdef HAVE_FTIME
162
Daniel Veillard01c13b52002-12-10 15:19:08 +0000163static int
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000164my_gettimeofday(struct timeval *tvp, void *tzp)
165{
166 struct timeb timebuffer;
167
168 ftime(&timebuffer);
169 if (tvp) {
170 tvp->tv_sec = timebuffer.time;
171 tvp->tv_usec = timebuffer.millitm * 1000L;
172 }
173 return (0);
174}
175#define HAVE_GETTIMEOFDAY 1
176#define gettimeofday my_gettimeofday
177
178#endif /* HAVE_FTIME */
179#endif /* HAVE_SYS_TIME_H */
180#endif /* HAVE_SYS_TIMEB_H */
181#endif /* !HAVE_GETTIMEOFDAY */
182
Daniel Veillard01db67c2001-12-18 07:09:59 +0000183#if defined(HAVE_GETTIMEOFDAY)
184static struct timeval begin, end;
185
186/*
187 * startTimer: call where you want to start timing
188 */
189static void
190startTimer(void)
191{
192 gettimeofday(&begin, NULL);
193}
194
195/*
196 * endTimer: call where you want to stop timing and to print out a
197 * message about the timing performed; format is a printf
198 * type argument
199 */
200static void
Daniel Veillard118aed72002-09-24 14:13:13 +0000201endTimer(const char *fmt, ...)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000202{
203 long msec;
204 va_list ap;
205
206 gettimeofday(&end, NULL);
207 msec = end.tv_sec - begin.tv_sec;
208 msec *= 1000;
209 msec += (end.tv_usec - begin.tv_usec) / 1000;
210
211#ifndef HAVE_STDARG_H
212#error "endTimer required stdarg functions"
213#endif
Daniel Veillard118aed72002-09-24 14:13:13 +0000214 va_start(ap, fmt);
215 vfprintf(stderr, fmt, ap);
Daniel Veillard01db67c2001-12-18 07:09:59 +0000216 va_end(ap);
217
218 fprintf(stderr, " took %ld ms\n", msec);
219}
220#elif defined(HAVE_TIME_H)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000221/*
222 * No gettimeofday function, so we have to make do with calling clock.
223 * This is obviously less accurate, but there's little we can do about
224 * that.
225 */
Daniel Veillard90bc3712002-03-07 15:12:58 +0000226#ifndef CLOCKS_PER_SEC
227#define CLOCKS_PER_SEC 100
228#endif
Daniel Veillard01db67c2001-12-18 07:09:59 +0000229
230static clock_t begin, end;
231static void
232startTimer(void)
233{
234 begin = clock();
235}
236static void
237endTimer(const char *fmt, ...)
238{
239 long msec;
240 va_list ap;
241
242 end = clock();
243 msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
244
245#ifndef HAVE_STDARG_H
246#error "endTimer required stdarg functions"
247#endif
248 va_start(ap, fmt);
249 vfprintf(stderr, fmt, ap);
250 va_end(ap);
251 fprintf(stderr, " took %ld ms\n", msec);
252}
253#else
254
255/*
256 * We don't have a gettimeofday or time.h, so we just don't do timing
257 */
258static void
259startTimer(void)
260{
261 /*
262 * Do nothing
263 */
264}
265static void
266endTimer(char *format, ...)
267{
268 /*
269 * We cannot do anything because we don't have a timing function
270 */
271#ifdef HAVE_STDARG_H
272 va_start(ap, format);
273 vfprintf(stderr, format, ap);
274 va_end(ap);
275 fprintf(stderr, " was not timed\n", msec);
276#else
277 /* We don't have gettimeofday, time or stdarg.h, what crazy world is
278 * this ?!
279 */
280#endif
281}
282#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000283/************************************************************************
284 * *
285 * HTML ouput *
286 * *
287 ************************************************************************/
288char buffer[50000];
289
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000290static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000291xmlHTMLEncodeSend(void) {
292 char *result;
293
294 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
295 if (result) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000296 xmlGenericError(xmlGenericErrorContext, "%s", result);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000297 xmlFree(result);
298 }
299 buffer[0] = 0;
300}
301
302/**
303 * xmlHTMLPrintFileInfo:
304 * @input: an xmlParserInputPtr input
305 *
306 * Displays the associated file and line informations for the current input
307 */
308
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000309static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000310xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000311 int len;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000312 xmlGenericError(xmlGenericErrorContext, "<p>");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000313
314 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000315 if (input != NULL) {
316 if (input->filename) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000317 snprintf(&buffer[len], sizeof(buffer) - len, "%s:%d: ", input->filename,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000318 input->line);
319 } else {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000320 snprintf(&buffer[len], sizeof(buffer) - len, "Entity: line %d: ", input->line);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000321 }
322 }
323 xmlHTMLEncodeSend();
324}
325
326/**
327 * xmlHTMLPrintFileContext:
328 * @input: an xmlParserInputPtr input
329 *
330 * Displays current context within the input content for error tracking
331 */
332
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000333static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000334xmlHTMLPrintFileContext(xmlParserInputPtr input) {
335 const xmlChar *cur, *base;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000336 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000337 int n;
338
339 if (input == NULL) return;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000340 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000341 cur = input->cur;
342 base = input->base;
343 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
344 cur--;
345 }
346 n = 0;
347 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
348 cur--;
349 if ((*cur == '\n') || (*cur == '\r')) cur++;
350 base = cur;
351 n = 0;
352 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000353 len = strlen(buffer);
354 snprintf(&buffer[len], sizeof(buffer) - len, "%c",
355 (unsigned char) *cur++);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000356 n++;
357 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000358 len = strlen(buffer);
359 snprintf(&buffer[len], sizeof(buffer) - len, "\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000360 cur = input->cur;
361 while ((*cur == '\n') || (*cur == '\r'))
362 cur--;
363 n = 0;
364 while ((cur != base) && (n++ < 80)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000365 len = strlen(buffer);
366 snprintf(&buffer[len], sizeof(buffer) - len, " ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000367 base++;
368 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000369 len = strlen(buffer);
370 snprintf(&buffer[len], sizeof(buffer) - len, "^\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000371 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000372 xmlGenericError(xmlGenericErrorContext, "</pre>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000373}
374
375/**
376 * xmlHTMLError:
377 * @ctx: an XML parser context
378 * @msg: the message to display/transmit
379 * @...: extra parameters for the message display
380 *
381 * Display and format an error messages, gives file, line, position and
382 * extra parameters.
383 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000384static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000385xmlHTMLError(void *ctx, const char *msg, ...)
386{
387 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
388 xmlParserInputPtr input;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000389 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000390 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000391
392 buffer[0] = 0;
393 input = ctxt->input;
394 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000395 input = ctxt->inputTab[ctxt->inputNr - 2];
396 }
397
398 xmlHTMLPrintFileInfo(input);
399
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000400 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000401 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000402 len = strlen(buffer);
403 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000404 va_end(args);
405 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000406 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000407
408 xmlHTMLPrintFileContext(input);
409 xmlHTMLEncodeSend();
410}
411
412/**
413 * xmlHTMLWarning:
414 * @ctx: an XML parser context
415 * @msg: the message to display/transmit
416 * @...: extra parameters for the message display
417 *
418 * Display and format a warning messages, gives file, line, position and
419 * extra parameters.
420 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000421static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000422xmlHTMLWarning(void *ctx, const char *msg, ...)
423{
424 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
425 xmlParserInputPtr input;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000426 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000427 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000428
429 buffer[0] = 0;
430 input = ctxt->input;
431 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000432 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 ************************************************************************/
Daniel Veillard7704fb12003-01-03 16:19:51 +0000590static void processNode(xmlTextReaderPtr reader) {
Daniel Veillarde59494f2003-01-04 16:35:29 +0000591 xmlChar *name, *value;
Daniel Veillard7704fb12003-01-03 16:19:51 +0000592
Daniel Veillarde59494f2003-01-04 16:35:29 +0000593 name = xmlTextReaderName(reader);
594 if (name == NULL)
595 name = xmlStrdup(BAD_CAST "--");
Daniel Veillard99737f52003-03-22 14:55:50 +0000596
Daniel Veillarde59494f2003-01-04 16:35:29 +0000597 value = xmlTextReaderValue(reader);
Daniel Veillard7704fb12003-01-03 16:19:51 +0000598
Daniel Veillard99737f52003-03-22 14:55:50 +0000599 printf("%d %d %s %d %d",
Daniel Veillarde59494f2003-01-04 16:35:29 +0000600 xmlTextReaderDepth(reader),
601 xmlTextReaderNodeType(reader),
602 name,
Daniel Veillard99737f52003-03-22 14:55:50 +0000603 xmlTextReaderIsEmptyElement(reader),
604 xmlTextReaderHasValue(reader));
Daniel Veillarde59494f2003-01-04 16:35:29 +0000605 xmlFree(name);
606 if (value == NULL)
607 printf("\n");
608 else {
609 printf(" %s\n", value);
610 xmlFree(value);
Daniel Veillard7704fb12003-01-03 16:19:51 +0000611 }
612}
613
614static void streamFile(char *filename) {
615 xmlTextReaderPtr reader;
616 int ret;
617
Daniel Veillard7704fb12003-01-03 16:19:51 +0000618 reader = xmlNewTextReaderFilename(filename);
619 if (reader != NULL) {
620 if (valid)
621 xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
Daniel Veillardce192eb2003-04-16 15:58:05 +0000622 else
623 xmlTextReaderSetParserProp(reader, XML_PARSER_LOADDTD, 1);
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000624#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +0000625 if (relaxng != NULL) {
626 if (timing) {
627 startTimer();
628 }
629 ret = xmlTextReaderRelaxNGValidate(reader, relaxng);
630 if (ret < 0) {
631 xmlGenericError(xmlGenericErrorContext,
632 "Relax-NG schema %s failed to compile\n", relaxng);
633 relaxng = NULL;
634 }
635 if (timing) {
636 endTimer("Compiling the schemas");
637 }
638 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000639#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +0000640
641 /*
642 * Process all nodes in sequence
643 */
Daniel Veillardce192eb2003-04-16 15:58:05 +0000644 if (timing) {
645 startTimer();
646 }
Daniel Veillard7704fb12003-01-03 16:19:51 +0000647 ret = xmlTextReaderRead(reader);
648 while (ret == 1) {
649 if (debug)
650 processNode(reader);
651 ret = xmlTextReaderRead(reader);
652 }
Daniel Veillardce192eb2003-04-16 15:58:05 +0000653 if (timing) {
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000654#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +0000655 if ((valid) || (relaxng != NULL))
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000656#else
657 if (valid)
658#endif
Daniel Veillardce192eb2003-04-16 15:58:05 +0000659 endTimer("Parsing and validating");
660 else
661 endTimer("Parsing");
662 }
Daniel Veillard7704fb12003-01-03 16:19:51 +0000663
Daniel Veillardf6bad792003-04-11 19:38:54 +0000664 if (valid) {
665 if (xmlTextReaderIsValid(reader) != 1) {
666 xmlGenericError(xmlGenericErrorContext,
667 "Document %s does not validate\n", filename);
668 progresult = 3;
669 }
670 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000671#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf4e55762003-04-15 23:32:22 +0000672 if (relaxng != NULL) {
673 if (xmlTextReaderIsValid(reader) != 1) {
674 printf("%s fails to validate\n", filename);
675 progresult = 3;
676 } else {
677 printf("%s validates\n", filename);
678 }
679 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000680#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +0000681 /*
682 * Done, cleanup and status
683 */
684 xmlFreeTextReader(reader);
685 if (ret != 0) {
686 printf("%s : failed to parse\n", filename);
Daniel Veillardf6bad792003-04-11 19:38:54 +0000687 progresult = 1;
Daniel Veillard7704fb12003-01-03 16:19:51 +0000688 }
689 } else {
690 fprintf(stderr, "Unable to open %s\n", filename);
Daniel Veillardf6bad792003-04-11 19:38:54 +0000691 progresult = 1;
Daniel Veillard7704fb12003-01-03 16:19:51 +0000692 }
693}
694
695/************************************************************************
696 * *
697 * Tree Test processing *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000698 * *
699 ************************************************************************/
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000700static void parseAndPrintFile(char *filename) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000701 xmlDocPtr doc = NULL, tmp;
702
Daniel Veillard48b2f892001-02-25 16:11:03 +0000703 if ((timing) && (!repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +0000704 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +0000705
706
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000707 if (filename == NULL) {
708 if (generate) {
709 xmlNodePtr n;
710
711 doc = xmlNewDoc(BAD_CAST "1.0");
712 n = xmlNewNode(NULL, BAD_CAST "info");
713 xmlNodeSetContent(n, BAD_CAST "abc");
714 xmlDocSetRootElement(doc, n);
715 }
716 }
Daniel Veillard89cad532001-10-22 09:46:13 +0000717#ifdef LIBXML_DOCB_ENABLED
718 /*
719 * build an SGML tree from a string;
720 */
721 else if ((sgml) && (push)) {
722 FILE *f;
723
724 f = fopen(filename, "r");
725 if (f != NULL) {
726 int res, size = 3;
727 char chars[4096];
728 docbParserCtxtPtr ctxt;
729
730 /* if (repeat) */
731 size = 4096;
732 res = fread(chars, 1, 4, f);
733 if (res > 0) {
734 ctxt = docbCreatePushParserCtxt(NULL, NULL,
William M. Brack779af002003-08-01 15:55:39 +0000735 chars, res, filename, XML_CHAR_ENCODING_NONE);
Daniel Veillard89cad532001-10-22 09:46:13 +0000736 while ((res = fread(chars, 1, size, f)) > 0) {
737 docbParseChunk(ctxt, chars, res, 0);
738 }
739 docbParseChunk(ctxt, chars, 0, 1);
740 doc = ctxt->myDoc;
741 docbFreeParserCtxt(ctxt);
742 }
743 fclose(f);
744 }
745 } else if (sgml) {
746 doc = docbParseFile(filename, NULL);
747 }
748#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000749#ifdef LIBXML_HTML_ENABLED
William M. Brack78637da2003-07-31 14:47:38 +0000750 else if ((html) && (push)) {
751 FILE *f;
752
753 f = fopen(filename, "r");
754 if (f != NULL) {
755 int res, size = 3;
756 char chars[4096];
757 htmlParserCtxtPtr ctxt;
758
759 /* if (repeat) */
760 size = 4096;
761 res = fread(chars, 1, 4, f);
762 if (res > 0) {
763 ctxt = htmlCreatePushParserCtxt(NULL, NULL,
764 chars, res, filename, 0);
765 while ((res = fread(chars, 1, size, f)) > 0) {
766 htmlParseChunk(ctxt, chars, res, 0);
767 }
768 htmlParseChunk(ctxt, chars, 0, 1);
769 doc = ctxt->myDoc;
770 htmlFreeParserCtxt(ctxt);
771 }
772 fclose(f);
773 }
774 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000775 else if (html) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000776 doc = htmlParseFile(filename, NULL);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000777 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000778#endif /* LIBXML_HTML_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000779 else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000780 /*
781 * build an XML tree from a string;
782 */
783 if (push) {
784 FILE *f;
785
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000786 /* '-' Usually means stdin -<sven@zen.org> */
787 if ((filename[0] == '-') && (filename[1] == 0)) {
788 f = stdin;
789 } else {
790 f = fopen(filename, "r");
791 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000792 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +0000793 int ret;
Daniel Veillarda880b122003-04-21 21:36:41 +0000794 int res, size = 1024;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000795 char chars[1024];
796 xmlParserCtxtPtr ctxt;
797
Daniel Veillarda880b122003-04-21 21:36:41 +0000798 /* if (repeat) size = 1024; */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000799 res = fread(chars, 1, 4, f);
800 if (res > 0) {
801 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
802 chars, res, filename);
803 while ((res = fread(chars, 1, size, f)) > 0) {
804 xmlParseChunk(ctxt, chars, res, 0);
805 }
806 xmlParseChunk(ctxt, chars, 0, 1);
807 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +0000808 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000809 xmlFreeParserCtxt(ctxt);
Daniel Veillarde715dd22000-08-29 18:29:38 +0000810 if (!ret) {
811 xmlFreeDoc(doc);
812 doc = NULL;
813 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000814 }
815 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000816 } else if (testIO) {
817 int ret;
818 FILE *f;
819
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000820 /* '-' Usually means stdin -<sven@zen.org> */
821 if ((filename[0] == '-') && (filename[1] == 0)) {
822 f = stdin;
823 } else {
824 f = fopen(filename, "r");
825 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000826 if (f != NULL) {
827 xmlParserCtxtPtr ctxt;
828
829 ctxt = xmlCreateIOParserCtxt(NULL, NULL,
830 (xmlInputReadCallback) myRead,
831 (xmlInputCloseCallback) myClose,
832 f, XML_CHAR_ENCODING_NONE);
833 xmlParseDocument(ctxt);
834
835 ret = ctxt->wellFormed;
836 doc = ctxt->myDoc;
837 xmlFreeParserCtxt(ctxt);
838 if (!ret) {
839 xmlFreeDoc(doc);
840 doc = NULL;
841 }
842 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000843 } else if (recovery) {
844 doc = xmlRecoverFile(filename);
845 } else if (htmlout) {
846 int ret;
847 xmlParserCtxtPtr ctxt;
848 xmlSAXHandler silent, *old;
849
850 ctxt = xmlCreateFileParserCtxt(filename);
Daniel Veillard88a172f2000-08-04 18:23:10 +0000851
852 if (ctxt == NULL) {
Daniel Veillardcbaf3992001-12-31 16:16:02 +0000853 /* If xmlCreateFileParserCtxt() return NULL something
Daniel Veillard88a172f2000-08-04 18:23:10 +0000854 strange happened so we don't want to do anything. Do
855 we want to print an error message here?
856 <sven@zen.org> */
Daniel Veillard7ebb1ee2000-08-04 18:24:45 +0000857 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000858 } else {
859 memcpy(&silent, ctxt->sax, sizeof(silent));
860 old = ctxt->sax;
861 silent.error = xmlHTMLError;
862 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000863 silent.warning = xmlHTMLWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000864 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000865 silent.warning = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000866 silent.fatalError = xmlHTMLError;
867 ctxt->sax = &silent;
868 ctxt->vctxt.error = xmlHTMLValidityError;
869 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000870 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000871 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000872 ctxt->vctxt.warning = NULL;
873
Daniel Veillard88a172f2000-08-04 18:23:10 +0000874 xmlParseDocument(ctxt);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000875
Daniel Veillard88a172f2000-08-04 18:23:10 +0000876 ret = ctxt->wellFormed;
877 doc = ctxt->myDoc;
878 ctxt->sax = old;
879 xmlFreeParserCtxt(ctxt);
880 if (!ret) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000881 xmlFreeDoc(doc);
882 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000883 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000884 }
Daniel Veillard46e370e2000-07-21 20:32:03 +0000885#ifdef HAVE_SYS_MMAN_H
886 } else if (memory) {
887 int fd;
888 struct stat info;
889 const char *base;
890 if (stat(filename, &info) < 0)
891 return;
892 if ((fd = open(filename, O_RDONLY)) < 0)
893 return;
894 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillard29579362000-08-14 17:57:48 +0000895 if (base == (void *) MAP_FAILED)
Daniel Veillard46e370e2000-07-21 20:32:03 +0000896 return;
897
898 doc = xmlParseMemory((char *) base, info.st_size);
899 munmap((char *) base, info.st_size);
900#endif
Daniel Veillardea7751d2002-12-20 00:16:24 +0000901 } else if (valid) {
902 int ret;
903 xmlParserCtxtPtr ctxt;
904
905 ctxt = xmlCreateFileParserCtxt(filename);
906
907 if (ctxt == NULL) {
908 doc = NULL;
909 } else {
910 xmlParseDocument(ctxt);
911 if (ctxt->valid == 0)
912 progresult = 4;
913 ret = ctxt->wellFormed;
914 doc = ctxt->myDoc;
915 xmlFreeParserCtxt(ctxt);
916 if (!ret) {
917 xmlFreeDoc(doc);
918 doc = NULL;
919 }
920 }
921 } else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000922 doc = xmlParseFile(filename);
Daniel Veillardea7751d2002-12-20 00:16:24 +0000923 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000924 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000925
Daniel Veillard88a172f2000-08-04 18:23:10 +0000926 /*
927 * If we don't have a document we might as well give up. Do we
928 * want an error message here? <sven@zen.org> */
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000929 if (doc == NULL) {
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000930 progresult = 1;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000931 return;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000932 }
933
Daniel Veillard48b2f892001-02-25 16:11:03 +0000934 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +0000935 endTimer("Parsing");
Daniel Veillard48b2f892001-02-25 16:11:03 +0000936 }
937
Daniel Veillard29e43992001-12-13 22:21:58 +0000938 /*
939 * Remove DOCTYPE nodes
940 */
941 if (dropdtd) {
942 xmlDtdPtr dtd;
943
944 dtd = xmlGetIntSubset(doc);
945 if (dtd != NULL) {
946 xmlUnlinkNode((xmlNodePtr)dtd);
947 xmlFreeDtd(dtd);
948 }
949 }
950
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000951#ifdef LIBXML_XINCLUDE_ENABLED
Daniel Veillard48b2f892001-02-25 16:11:03 +0000952 if (xinclude) {
953 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +0000954 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +0000955 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000956 xmlXIncludeProcess(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000957 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +0000958 endTimer("Xinclude processing");
Daniel Veillard48b2f892001-02-25 16:11:03 +0000959 }
960 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000961#endif
Daniel Veillard88a172f2000-08-04 18:23:10 +0000962
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000963#ifdef LIBXML_DEBUG_ENABLED
964 /*
Daniel Veillardcbaf3992001-12-31 16:16:02 +0000965 * shell interaction
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000966 */
967 if (shell)
968 xmlShell(doc, filename, xmlShellReadline, stdout);
969#endif
970
971 /*
972 * test intermediate copy if needed.
973 */
974 if (copy) {
975 tmp = doc;
976 doc = xmlCopyDoc(doc, 1);
977 xmlFreeDoc(tmp);
978 }
979
980 if ((insert) && (!html)) {
981 const xmlChar* list[256];
982 int nb, i;
983 xmlNodePtr node;
984
985 if (doc->children != NULL) {
986 node = doc->children;
987 while ((node != NULL) && (node->last == NULL)) node = node->next;
988 if (node != NULL) {
989 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
990 if (nb < 0) {
991 printf("could not get valid list of elements\n");
992 } else if (nb == 0) {
MDT 2001 John Fleckbbb9e432001-09-24 03:08:43 +0000993 printf("No element can be inserted under root\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000994 } else {
MDT 2001 John Fleckbbb9e432001-09-24 03:08:43 +0000995 printf("%d element types can be inserted under root:\n",
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000996 nb);
997 for (i = 0;i < nb;i++) {
Daniel Veillard8a1b1852003-01-05 22:37:17 +0000998 printf("%s\n", (char *) list[i]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000999 }
1000 }
1001 }
1002 }
1003 }else if (noout == 0) {
1004 /*
1005 * print it.
1006 */
1007#ifdef LIBXML_DEBUG_ENABLED
1008 if (!debug) {
1009#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00001010 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001011 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001012 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +00001013#ifdef HAVE_SYS_MMAN_H
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001014 if (memory) {
1015 xmlChar *result;
1016 int len;
1017
1018 if (encoding != NULL) {
Daniel Veillardd536f702001-11-08 17:32:47 +00001019 if ( format ) {
1020 xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
1021 } else {
1022 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
1023 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001024 } else {
Daniel Veillard90493a92001-08-14 14:12:47 +00001025 if (format)
1026 xmlDocDumpFormatMemory(doc, &result, &len, 1);
1027 else
1028 xmlDocDumpMemory(doc, &result, &len);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001029 }
1030 if (result == NULL) {
1031 fprintf(stderr, "Failed to save\n");
1032 } else {
1033 write(1, result, len);
1034 xmlFree(result);
1035 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +00001036 } else
1037#endif /* HAVE_SYS_MMAN_H */
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001038 if (compress) {
1039 xmlSaveFile(output ? output : "-", doc);
1040 }
Daniel Veillardd536f702001-11-08 17:32:47 +00001041 else if (encoding != NULL) {
1042 if ( format ) {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001043 xmlSaveFormatFileEnc(output ? output : "-", doc, encoding, 1);
1044 }
Daniel Veillardd536f702001-11-08 17:32:47 +00001045 else {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001046 xmlSaveFileEnc(output ? output : "-", doc, encoding);
Daniel Veillardd536f702001-11-08 17:32:47 +00001047 }
1048 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001049 else if (format) {
1050 xmlSaveFormatFile(output ? output : "-", doc, 1);
1051 }
1052 else {
1053 FILE *out;
1054 if (output == NULL)
1055 out = stdout;
1056 else {
1057 out = fopen(output,"wb");
1058 }
1059 xmlDocDump(out, doc);
1060
1061 if (output)
1062 fclose(out);
1063 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001064 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001065 endTimer("Saving");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001066 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001067#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001068 } else {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001069 FILE *out;
1070 if (output == NULL)
1071 out = stdout;
1072 else {
1073 out = fopen(output,"wb");
1074 }
1075 xmlDebugDumpDocument(out, doc);
1076
1077 if (output)
1078 fclose(out);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001079 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001080#endif
1081 }
1082
1083 /*
1084 * A posteriori validation test
1085 */
Daniel Veillard66f68e72003-08-18 16:39:51 +00001086 if ((dtdvalid != NULL) || (dtdvalidfpi != NULL)) {
Daniel Veillardcd429612000-10-11 15:57:05 +00001087 xmlDtdPtr dtd;
1088
Daniel Veillard48b2f892001-02-25 16:11:03 +00001089 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001090 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001091 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00001092 if (dtdvalid != NULL)
1093 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
1094 else
1095 dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL);
Daniel Veillard48b2f892001-02-25 16:11:03 +00001096 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001097 endTimer("Parsing DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001098 }
Daniel Veillardcd429612000-10-11 15:57:05 +00001099 if (dtd == NULL) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00001100 if (dtdvalid != NULL)
1101 xmlGenericError(xmlGenericErrorContext,
1102 "Could not parse DTD %s\n", dtdvalid);
1103 else
1104 xmlGenericError(xmlGenericErrorContext,
1105 "Could not parse DTD %s\n", dtdvalidfpi);
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001106 progresult = 2;
Daniel Veillardcd429612000-10-11 15:57:05 +00001107 } else {
Daniel Veillarda37aab82003-06-09 09:10:36 +00001108 xmlValidCtxtPtr cvp;
1109
1110 if ((cvp = xmlNewValidCtxt()) == NULL) {
1111 xmlGenericError(xmlGenericErrorContext,
1112 "Couldn't allocate validation context\n");
1113 exit(-1);
1114 }
1115 cvp->userData = (void *) stderr;
1116 cvp->error = (xmlValidityErrorFunc) fprintf;
1117 cvp->warning = (xmlValidityWarningFunc) fprintf;
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 if (!xmlValidateDtd(cvp, doc, dtd)) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00001123 if (dtdvalid != NULL)
1124 xmlGenericError(xmlGenericErrorContext,
1125 "Document %s does not validate against %s\n",
1126 filename, dtdvalid);
1127 else
1128 xmlGenericError(xmlGenericErrorContext,
1129 "Document %s does not validate against %s\n",
1130 filename, dtdvalidfpi);
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001131 progresult = 3;
Daniel Veillardcd429612000-10-11 15:57:05 +00001132 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001133 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001134 endTimer("Validating against DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001135 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00001136 xmlFreeValidCtxt(cvp);
Daniel Veillardcd429612000-10-11 15:57:05 +00001137 xmlFreeDtd(dtd);
1138 }
1139 } else if (postvalid) {
Daniel Veillarda37aab82003-06-09 09:10:36 +00001140 xmlValidCtxtPtr cvp;
1141
1142 if ((cvp = xmlNewValidCtxt()) == NULL) {
1143 xmlGenericError(xmlGenericErrorContext,
1144 "Couldn't allocate validation context\n");
1145 exit(-1);
1146 }
1147
Daniel Veillard48b2f892001-02-25 16:11:03 +00001148 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001149 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001150 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00001151 cvp->userData = (void *) stderr;
1152 cvp->error = (xmlValidityErrorFunc) fprintf;
1153 cvp->warning = (xmlValidityWarningFunc) fprintf;
1154 if (!xmlValidateDocument(cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001155 xmlGenericError(xmlGenericErrorContext,
1156 "Document %s does not validate\n", filename);
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001157 progresult = 3;
Daniel Veillardcd429612000-10-11 15:57:05 +00001158 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001159 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001160 endTimer("Validating");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001161 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00001162 xmlFreeValidCtxt(cvp);
Daniel Veillard71531f32003-02-05 13:19:53 +00001163#ifdef LIBXML_SCHEMAS_ENABLED
1164 } else if (relaxngschemas != NULL) {
1165 xmlRelaxNGValidCtxtPtr ctxt;
1166 int ret;
1167
Daniel Veillard42f12e92003-03-07 18:32:59 +00001168 if ((timing) && (!repeat)) {
1169 startTimer();
1170 }
1171
Daniel Veillard71531f32003-02-05 13:19:53 +00001172 ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
1173 xmlRelaxNGSetValidErrors(ctxt,
1174 (xmlRelaxNGValidityErrorFunc) fprintf,
1175 (xmlRelaxNGValidityWarningFunc) fprintf,
1176 stderr);
1177 ret = xmlRelaxNGValidateDoc(ctxt, doc);
1178 if (ret == 0) {
1179 printf("%s validates\n", filename);
1180 } else if (ret > 0) {
1181 printf("%s fails to validate\n", filename);
1182 } else {
1183 printf("%s validation generated an internal error\n",
1184 filename);
1185 }
1186 xmlRelaxNGFreeValidCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00001187 if ((timing) && (!repeat)) {
1188 endTimer("Validating");
1189 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001190 } else if (wxschemas != NULL) {
1191 xmlSchemaValidCtxtPtr ctxt;
1192 int ret;
1193
1194 if ((timing) && (!repeat)) {
1195 startTimer();
1196 }
1197
1198 ctxt = xmlSchemaNewValidCtxt(wxschemas);
1199 xmlSchemaSetValidErrors(ctxt,
1200 (xmlSchemaValidityErrorFunc) fprintf,
1201 (xmlSchemaValidityWarningFunc) fprintf,
1202 stderr);
1203 ret = xmlSchemaValidateDoc(ctxt, doc);
1204 if (ret == 0) {
1205 printf("%s validates\n", filename);
1206 } else if (ret > 0) {
1207 printf("%s fails to validate\n", filename);
1208 } else {
1209 printf("%s validation generated an internal error\n",
1210 filename);
1211 }
1212 xmlSchemaFreeValidCtxt(ctxt);
1213 if ((timing) && (!repeat)) {
1214 endTimer("Validating");
1215 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001216#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001217 }
1218
1219#ifdef LIBXML_DEBUG_ENABLED
1220 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001221 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001222#endif
1223
1224 /*
1225 * free it.
1226 */
Daniel Veillard48b2f892001-02-25 16:11:03 +00001227 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001228 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001229 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001230 xmlFreeDoc(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +00001231 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001232 endTimer("Freeing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001233 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001234}
1235
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001236/************************************************************************
1237 * *
1238 * Usage and Main *
1239 * *
1240 ************************************************************************/
1241
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00001242static void showVersion(const char *name) {
1243 fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
1244 fprintf(stderr, " compiled with: ");
1245#ifdef LIBXML_FTP_ENABLED
1246 fprintf(stderr, "FTP ");
1247#endif
1248#ifdef LIBXML_HTTP_ENABLED
1249 fprintf(stderr, "HTTP ");
1250#endif
1251#ifdef LIBXML_HTML_ENABLED
1252 fprintf(stderr, "HTML ");
1253#endif
1254#ifdef LIBXML_C14N_ENABLED
1255 fprintf(stderr, "C14N ");
1256#endif
1257#ifdef LIBXML_CATALOG_ENABLED
1258 fprintf(stderr, "Catalog ");
1259#endif
1260#ifdef LIBXML_DOCB_ENABLED
1261 fprintf(stderr, "DocBook ");
1262#endif
1263#ifdef LIBXML_XPATH_ENABLED
1264 fprintf(stderr, "XPath ");
1265#endif
1266#ifdef LIBXML_XPTR_ENABLED
1267 fprintf(stderr, "XPointer ");
1268#endif
1269#ifdef LIBXML_XINCLUDE_ENABLED
1270 fprintf(stderr, "XInclude ");
1271#endif
1272#ifdef LIBXML_ICONV_ENABLED
1273 fprintf(stderr, "Iconv ");
1274#endif
1275#ifdef DEBUG_MEMORY_LOCATION
1276 fprintf(stderr, "MemDebug ");
1277#endif
1278#ifdef LIBXML_UNICODE_ENABLED
1279 fprintf(stderr, "Unicode ");
1280#endif
1281#ifdef LIBXML_REGEXP_ENABLED
1282 fprintf(stderr, "Regexps ");
1283#endif
1284#ifdef LIBXML_AUTOMATA_ENABLED
1285 fprintf(stderr, "Automata ");
1286#endif
1287#ifdef LIBXML_SCHEMAS_ENABLED
1288 fprintf(stderr, "Schemas ");
1289#endif
1290 fprintf(stderr, "\n");
1291}
1292
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001293static void usage(const char *name) {
1294 printf("Usage : %s [options] XMLfiles ...\n", name);
1295 printf("\tParse the XML files and output the result of the parsing\n");
1296 printf("\t--version : display the version of the XML library used\n");
1297#ifdef LIBXML_DEBUG_ENABLED
1298 printf("\t--debug : dump a debug tree of the in-memory document\n");
1299 printf("\t--shell : run a navigating shell\n");
1300 printf("\t--debugent : debug the entities defined in the document\n");
Daniel Veillard8326e732003-01-07 00:19:07 +00001301#else
1302 printf("\t--debug : dump the nodes content when using --stream\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001303#endif
1304 printf("\t--copy : used to test the internal copy implementation\n");
1305 printf("\t--recover : output what was parsable on broken XML documents\n");
1306 printf("\t--noent : substitute entity references by their value\n");
1307 printf("\t--noout : don't output the result tree\n");
Daniel Veillarde8b09e42003-05-13 22:14:13 +00001308 printf("\t--nonet : refuse to fetch DTDs or entities over network\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001309 printf("\t--htmlout : output results as HTML\n");
Daniel Veillard05c13a22001-09-09 08:38:09 +00001310 printf("\t--nowrap : do not put HTML doc wrapper\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001311 printf("\t--valid : validate the document in addition to std well-formed check\n");
1312 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
1313 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
Daniel Veillard66f68e72003-08-18 16:39:51 +00001314 printf("\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001315 printf("\t--timing : print some timings\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001316 printf("\t--output file or -o file: save to a given file\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001317 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
1318 printf("\t--insert : ad-hoc test for valid insertions\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001319#ifdef HAVE_ZLIB_H
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001320 printf("\t--compress : turn on gzip compression of output\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001321#endif
Daniel Veillard89cad532001-10-22 09:46:13 +00001322#ifdef LIBXML_DOCB_ENABLED
1323 printf("\t--sgml : use the DocBook SGML parser\n");
1324#endif
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001325#ifdef LIBXML_HTML_ENABLED
1326 printf("\t--html : use the HTML parser\n");
1327#endif
1328 printf("\t--push : use the push mode of the parser\n");
1329#ifdef HAVE_SYS_MMAN_H
1330 printf("\t--memory : parse from memory\n");
1331#endif
1332 printf("\t--nowarning : do not emit warnings from parser/validator\n");
1333 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
Daniel Veillard90493a92001-08-14 14:12:47 +00001334 printf("\t--format : reformat/reindent the input\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001335 printf("\t--testIO : test user I/O support\n");
1336 printf("\t--encode encoding : output in the given encoding\n");
1337#ifdef LIBXML_CATALOG_ENABLED
Daniel Veillardbd9b0e82001-11-26 10:32:08 +00001338 printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
1339 printf("\t otherwise XML Catalogs starting from \n");
Daniel Veillard3be27512003-01-26 19:49:04 +00001340 printf("\t " XML_XML_DEFAULT_CATALOG " are activated by default\n");
Daniel Veillard05c13a22001-09-09 08:38:09 +00001341 printf("\t--nocatalogs: deactivate all catalogs\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001342#endif
1343 printf("\t--auto : generate a small doc on the fly\n");
1344#ifdef LIBXML_XINCLUDE_ENABLED
1345 printf("\t--xinclude : do XInclude processing\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001346#endif
Daniel Veillardcbaf3992001-12-31 16:16:02 +00001347 printf("\t--loaddtd : fetch external DTD\n");
Daniel Veillard48da9102001-08-07 01:10:10 +00001348 printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
Daniel Veillard29e43992001-12-13 22:21:58 +00001349 printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
Daniel Veillard7704fb12003-01-03 16:19:51 +00001350 printf("\t--stream : use the streaming interface to process very large files\n");
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001351 printf("\t--chkregister : verify the node registration code\n");
Daniel Veillardef4d3bc2003-02-07 12:38:22 +00001352#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard71531f32003-02-05 13:19:53 +00001353 printf("\t--relaxng schema : do RelaxNG validation against the schema\n");
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001354 printf("\t--schema schema : do validation against the WXS schema\n");
Daniel Veillard71531f32003-02-05 13:19:53 +00001355#endif
Daniel Veillarda42f25f2002-01-25 14:15:40 +00001356 printf("\nLibxml project home page: http://xmlsoft.org/\n");
1357 printf("To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001358}
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001359
1360static void registerNode(xmlNodePtr node)
1361{
1362 node->_private = malloc(sizeof(long));
1363 *(long*)node->_private = (long) 0x81726354;
1364}
1365
1366static void deregisterNode(xmlNodePtr node)
1367{
1368 assert(node->_private != NULL);
1369 assert(*(long*)node->_private == (long) 0x81726354);
1370 free(node->_private);
1371}
1372
Daniel Veillard4a6845d2001-01-03 13:32:39 +00001373int
1374main(int argc, char **argv) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00001375 int i, acount;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001376 int files = 0;
Daniel Veillard845cce42002-01-09 11:51:37 +00001377 int version = 0;
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00001378 const char* indent;
1379
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001380 if (argc <= 1) {
1381 usage(argv[0]);
1382 return(1);
1383 }
Daniel Veillardbe803962000-06-28 23:40:59 +00001384 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001385 for (i = 1; i < argc ; i++) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001386 if (!strcmp(argv[i], "-"))
1387 break;
1388
1389 if (argv[i][0] != '-')
1390 continue;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001391 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
1392 debug++;
Daniel Veillard56ada1d2003-01-07 11:17:25 +00001393 else
1394#ifdef LIBXML_DEBUG_ENABLED
1395 if ((!strcmp(argv[i], "-shell")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001396 (!strcmp(argv[i], "--shell"))) {
1397 shell++;
1398 noout = 1;
1399 } else
1400#endif
1401 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
1402 copy++;
1403 else if ((!strcmp(argv[i], "-recover")) ||
1404 (!strcmp(argv[i], "--recover")))
1405 recovery++;
1406 else if ((!strcmp(argv[i], "-noent")) ||
1407 (!strcmp(argv[i], "--noent")))
1408 noent++;
Daniel Veillard4ec885a2001-06-17 10:31:07 +00001409 else if ((!strcmp(argv[i], "-version")) ||
Daniel Veillard845cce42002-01-09 11:51:37 +00001410 (!strcmp(argv[i], "--version"))) {
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00001411 showVersion(argv[0]);
Daniel Veillard845cce42002-01-09 11:51:37 +00001412 version = 1;
1413 } else if ((!strcmp(argv[i], "-noout")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001414 (!strcmp(argv[i], "--noout")))
1415 noout++;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001416 else if ((!strcmp(argv[i], "-o")) ||
1417 (!strcmp(argv[i], "-output")) ||
1418 (!strcmp(argv[i], "--output"))) {
1419 i++;
Daniel Veillard6e4f1c02002-04-09 09:55:20 +00001420 output = argv[i];
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001421 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001422 else if ((!strcmp(argv[i], "-htmlout")) ||
1423 (!strcmp(argv[i], "--htmlout")))
1424 htmlout++;
Daniel Veillard89cad532001-10-22 09:46:13 +00001425#ifdef LIBXML_DOCB_ENABLED
1426 else if ((!strcmp(argv[i], "-sgml")) ||
1427 (!strcmp(argv[i], "--sgml"))) {
1428 sgml++;
1429 }
1430#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001431#ifdef LIBXML_HTML_ENABLED
1432 else if ((!strcmp(argv[i], "-html")) ||
1433 (!strcmp(argv[i], "--html"))) {
1434 html++;
1435 }
1436#endif /* LIBXML_HTML_ENABLED */
1437 else if ((!strcmp(argv[i], "-nowrap")) ||
1438 (!strcmp(argv[i], "--nowrap")))
1439 nowrap++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001440 else if ((!strcmp(argv[i], "-loaddtd")) ||
1441 (!strcmp(argv[i], "--loaddtd")))
1442 loaddtd++;
Daniel Veillard48da9102001-08-07 01:10:10 +00001443 else if ((!strcmp(argv[i], "-dtdattr")) ||
1444 (!strcmp(argv[i], "--dtdattr"))) {
1445 loaddtd++;
1446 dtdattrs++;
1447 } else if ((!strcmp(argv[i], "-valid")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001448 (!strcmp(argv[i], "--valid")))
1449 valid++;
1450 else if ((!strcmp(argv[i], "-postvalid")) ||
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001451 (!strcmp(argv[i], "--postvalid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001452 postvalid++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001453 loaddtd++;
1454 } else if ((!strcmp(argv[i], "-dtdvalid")) ||
Daniel Veillardcd429612000-10-11 15:57:05 +00001455 (!strcmp(argv[i], "--dtdvalid"))) {
1456 i++;
1457 dtdvalid = argv[i];
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001458 loaddtd++;
Daniel Veillard66f68e72003-08-18 16:39:51 +00001459 } else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
1460 (!strcmp(argv[i], "--dtdvalidfpi"))) {
1461 i++;
1462 dtdvalidfpi = argv[i];
1463 loaddtd++;
Daniel Veillardcd429612000-10-11 15:57:05 +00001464 }
Daniel Veillard29e43992001-12-13 22:21:58 +00001465 else if ((!strcmp(argv[i], "-dropdtd")) ||
1466 (!strcmp(argv[i], "--dropdtd")))
1467 dropdtd++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001468 else if ((!strcmp(argv[i], "-insert")) ||
1469 (!strcmp(argv[i], "--insert")))
1470 insert++;
Daniel Veillard48b2f892001-02-25 16:11:03 +00001471 else if ((!strcmp(argv[i], "-timing")) ||
1472 (!strcmp(argv[i], "--timing")))
1473 timing++;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001474 else if ((!strcmp(argv[i], "-auto")) ||
1475 (!strcmp(argv[i], "--auto")))
1476 generate++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001477 else if ((!strcmp(argv[i], "-repeat")) ||
1478 (!strcmp(argv[i], "--repeat")))
1479 repeat++;
1480 else if ((!strcmp(argv[i], "-push")) ||
1481 (!strcmp(argv[i], "--push")))
1482 push++;
Daniel Veillard46e370e2000-07-21 20:32:03 +00001483#ifdef HAVE_SYS_MMAN_H
1484 else if ((!strcmp(argv[i], "-memory")) ||
1485 (!strcmp(argv[i], "--memory")))
1486 memory++;
1487#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +00001488 else if ((!strcmp(argv[i], "-testIO")) ||
1489 (!strcmp(argv[i], "--testIO")))
1490 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00001491#ifdef LIBXML_XINCLUDE_ENABLED
1492 else if ((!strcmp(argv[i], "-xinclude")) ||
1493 (!strcmp(argv[i], "--xinclude")))
1494 xinclude++;
1495#endif
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001496#ifdef HAVE_ZLIB_H
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001497 else if ((!strcmp(argv[i], "-compress")) ||
1498 (!strcmp(argv[i], "--compress"))) {
1499 compress++;
1500 xmlSetCompressMode(9);
1501 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001502#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001503 else if ((!strcmp(argv[i], "-nowarning")) ||
1504 (!strcmp(argv[i], "--nowarning"))) {
1505 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001506 xmlPedanticParserDefault(0);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001507 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001508 else if ((!strcmp(argv[i], "-pedantic")) ||
1509 (!strcmp(argv[i], "--pedantic"))) {
1510 xmlGetWarningsDefaultValue = 1;
1511 xmlPedanticParserDefault(1);
1512 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00001513#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001514 else if ((!strcmp(argv[i], "-debugent")) ||
1515 (!strcmp(argv[i], "--debugent"))) {
1516 debugent++;
1517 xmlParserDebugEntities = 1;
1518 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00001519#endif
Daniel Veillard81418e32001-05-22 15:08:55 +00001520#ifdef LIBXML_CATALOG_ENABLED
1521 else if ((!strcmp(argv[i], "-catalogs")) ||
1522 (!strcmp(argv[i], "--catalogs"))) {
Daniel Veillarde2940dd2001-08-22 00:06:49 +00001523 catalogs++;
1524 } else if ((!strcmp(argv[i], "-nocatalogs")) ||
1525 (!strcmp(argv[i], "--nocatalogs"))) {
1526 nocatalogs++;
Daniel Veillard81418e32001-05-22 15:08:55 +00001527 }
1528#endif
Daniel Veillardbe803962000-06-28 23:40:59 +00001529 else if ((!strcmp(argv[i], "-encode")) ||
1530 (!strcmp(argv[i], "--encode"))) {
1531 i++;
1532 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001533 /*
1534 * OK it's for testing purposes
1535 */
1536 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +00001537 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001538 else if ((!strcmp(argv[i], "-noblanks")) ||
1539 (!strcmp(argv[i], "--noblanks"))) {
1540 noblanks++;
1541 xmlKeepBlanksDefault(0);
Daniel Veillard90493a92001-08-14 14:12:47 +00001542 }
1543 else if ((!strcmp(argv[i], "-format")) ||
1544 (!strcmp(argv[i], "--format"))) {
1545 noblanks++;
1546 format++;
1547 xmlKeepBlanksDefault(0);
Daniel Veillard7704fb12003-01-03 16:19:51 +00001548 }
1549 else if ((!strcmp(argv[i], "-stream")) ||
1550 (!strcmp(argv[i], "--stream"))) {
1551 stream++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001552 }
1553 else if ((!strcmp(argv[i], "-chkregister")) ||
1554 (!strcmp(argv[i], "--chkregister"))) {
1555 chkregister++;
Daniel Veillard71531f32003-02-05 13:19:53 +00001556#ifdef LIBXML_SCHEMAS_ENABLED
1557 } else if ((!strcmp(argv[i], "-relaxng")) ||
1558 (!strcmp(argv[i], "--relaxng"))) {
1559 i++;
1560 relaxng = argv[i];
1561 noent++;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001562 } else if ((!strcmp(argv[i], "-schema")) ||
1563 (!strcmp(argv[i], "--schema"))) {
1564 i++;
1565 schema = argv[i];
1566 noent++;
Daniel Veillard71531f32003-02-05 13:19:53 +00001567#endif
Daniel Veillarde8b09e42003-05-13 22:14:13 +00001568 } else if ((!strcmp(argv[i], "-nonet")) ||
1569 (!strcmp(argv[i], "--nonet"))) {
1570 xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001571 } else {
1572 fprintf(stderr, "Unknown option %s\n", argv[i]);
1573 usage(argv[0]);
1574 return(1);
1575 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001576 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00001577
1578#ifdef LIBXML_CATALOG_ENABLED
1579 if (nocatalogs == 0) {
1580 if (catalogs) {
1581 const char *catal;
1582
1583 catal = getenv("SGML_CATALOG_FILES");
Daniel Veillard6c5f9d12001-08-25 13:33:14 +00001584 if (catal != NULL) {
1585 xmlLoadCatalogs(catal);
1586 } else {
1587 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
1588 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00001589 }
1590 }
1591#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001592
1593 if (chkregister) {
1594 xmlRegisterNodeDefault(registerNode);
1595 xmlDeregisterNodeDefault(deregisterNode);
1596 }
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00001597
1598 indent = getenv("XMLLINT_INDENT");
1599 if(indent != NULL) {
1600 xmlTreeIndentString = indent;
1601 }
1602
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001603
Daniel Veillardd9bad132001-07-23 19:39:43 +00001604 xmlLineNumbersDefault(1);
Daniel Veillard48da9102001-08-07 01:10:10 +00001605 if (loaddtd != 0)
1606 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
1607 if (dtdattrs)
1608 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001609 if (noent != 0) xmlSubstituteEntitiesDefault(1);
1610 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
1611 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001612 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001613 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001614 xmlGenericError(xmlGenericErrorContext,
1615 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
1616 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001617 "<html><head><title>%s output</title></head>\n",
1618 argv[0]);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001619 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001620 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
1621 argv[0]);
1622 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001623
1624#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +00001625 if ((relaxng != NULL) && (stream == 0)) {
Daniel Veillard71531f32003-02-05 13:19:53 +00001626 xmlRelaxNGParserCtxtPtr ctxt;
1627
Daniel Veillardce192eb2003-04-16 15:58:05 +00001628 /* forces loading the DTDs */
1629 xmlLoadExtDtdDefaultValue |= 1;
Daniel Veillard42f12e92003-03-07 18:32:59 +00001630 if (timing) {
1631 startTimer();
1632 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001633 ctxt = xmlRelaxNGNewParserCtxt(relaxng);
1634 xmlRelaxNGSetParserErrors(ctxt,
1635 (xmlRelaxNGValidityErrorFunc) fprintf,
1636 (xmlRelaxNGValidityWarningFunc) fprintf,
1637 stderr);
1638 relaxngschemas = xmlRelaxNGParse(ctxt);
Daniel Veillardce192eb2003-04-16 15:58:05 +00001639 if (relaxngschemas == NULL) {
1640 xmlGenericError(xmlGenericErrorContext,
1641 "Relax-NG schema %s failed to compile\n", relaxng);
1642 relaxng = NULL;
1643 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001644 xmlRelaxNGFreeParserCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00001645 if (timing) {
1646 endTimer("Compiling the schemas");
1647 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001648 } else if ((schema != NULL) && (stream == 0)) {
1649 xmlSchemaParserCtxtPtr ctxt;
1650
1651 if (timing) {
1652 startTimer();
1653 }
1654 ctxt = xmlSchemaNewParserCtxt(schema);
1655 xmlSchemaSetParserErrors(ctxt,
1656 (xmlSchemaValidityErrorFunc) fprintf,
1657 (xmlSchemaValidityWarningFunc) fprintf,
1658 stderr);
1659 wxschemas = xmlSchemaParse(ctxt);
1660 if (wxschemas == NULL) {
1661 xmlGenericError(xmlGenericErrorContext,
1662 "WXS schema %s failed to compile\n", schema);
1663 schema = NULL;
1664 }
1665 xmlSchemaFreeParserCtxt(ctxt);
1666 if (timing) {
1667 endTimer("Compiling the schemas");
1668 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001669 }
1670#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001671 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +00001672 if ((!strcmp(argv[i], "-encode")) ||
1673 (!strcmp(argv[i], "--encode"))) {
1674 i++;
1675 continue;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001676 } else if ((!strcmp(argv[i], "-o")) ||
1677 (!strcmp(argv[i], "-output")) ||
1678 (!strcmp(argv[i], "--output"))) {
1679 i++;
1680 continue;
Daniel Veillardbe803962000-06-28 23:40:59 +00001681 }
Daniel Veillardcd429612000-10-11 15:57:05 +00001682 if ((!strcmp(argv[i], "-dtdvalid")) ||
1683 (!strcmp(argv[i], "--dtdvalid"))) {
1684 i++;
1685 continue;
1686 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00001687 if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
1688 (!strcmp(argv[i], "--dtdvalidfpi"))) {
1689 i++;
1690 continue;
1691 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001692 if ((!strcmp(argv[i], "-relaxng")) ||
1693 (!strcmp(argv[i], "--relaxng"))) {
1694 i++;
1695 continue;
1696 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001697 if ((!strcmp(argv[i], "-schema")) ||
1698 (!strcmp(argv[i], "--schema"))) {
1699 i++;
1700 continue;
1701 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001702 if ((timing) && (repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00001703 startTimer();
Daniel Veillardcbaf3992001-12-31 16:16:02 +00001704 /* Remember file names. "-" means stdin. <sven@zen.org> */
Daniel Veillard4a6845d2001-01-03 13:32:39 +00001705 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001706 if (repeat) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00001707 for (acount = 0;acount < 100 * repeat;acount++)
1708 if (stream != 0)
1709 streamFile(argv[i]);
1710 else
1711 parseAndPrintFile(argv[i]);
1712 } else {
1713 if (stream != 0)
1714 streamFile(argv[i]);
1715 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001716 parseAndPrintFile(argv[i]);
Daniel Veillard7704fb12003-01-03 16:19:51 +00001717 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001718 files ++;
Daniel Veillarda7866932001-12-04 13:14:44 +00001719 if ((timing) && (repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001720 endTimer("100 iterations");
Daniel Veillarda7866932001-12-04 13:14:44 +00001721 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001722 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001723 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001724 if (generate)
1725 parseAndPrintFile(NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001726 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001727 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001728 }
Daniel Veillard845cce42002-01-09 11:51:37 +00001729 if ((files == 0) && (!generate) && (version == 0)) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001730 usage(argv[0]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001731 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001732#ifdef LIBXML_SCHEMAS_ENABLED
1733 if (relaxngschemas != NULL)
1734 xmlRelaxNGFree(relaxngschemas);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001735 if (wxschemas != NULL)
1736 xmlSchemaFree(wxschemas);
Daniel Veillard71531f32003-02-05 13:19:53 +00001737 xmlRelaxNGCleanupTypes();
1738#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001739 xmlCleanupParser();
1740 xmlMemoryDump();
1741
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001742 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001743}
Daniel Veillard88a172f2000-08-04 18:23:10 +00001744