blob: 200ce687aea3c31367ba585e26486006624f3369 [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 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 Veillard07cb8222003-09-10 10:51:05 +0000151static int sax1 = 0;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +0000152static const char *output = NULL;
153
Daniel Veillard01db67c2001-12-18 07:09:59 +0000154/*
155 * Internal timing routines to remove the necessity to have unix-specific
156 * function calls
157 */
158
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000159#ifndef HAVE_GETTIMEOFDAY
160#ifdef HAVE_SYS_TIMEB_H
161#ifdef HAVE_SYS_TIME_H
162#ifdef HAVE_FTIME
163
Daniel Veillard01c13b52002-12-10 15:19:08 +0000164static int
Daniel Veillard8c1ae602002-03-07 11:21:00 +0000165my_gettimeofday(struct timeval *tvp, void *tzp)
166{
167 struct timeb timebuffer;
168
169 ftime(&timebuffer);
170 if (tvp) {
171 tvp->tv_sec = timebuffer.time;
172 tvp->tv_usec = timebuffer.millitm * 1000L;
173 }
174 return (0);
175}
176#define HAVE_GETTIMEOFDAY 1
177#define gettimeofday my_gettimeofday
178
179#endif /* HAVE_FTIME */
180#endif /* HAVE_SYS_TIME_H */
181#endif /* HAVE_SYS_TIMEB_H */
182#endif /* !HAVE_GETTIMEOFDAY */
183
Daniel Veillard01db67c2001-12-18 07:09:59 +0000184#if defined(HAVE_GETTIMEOFDAY)
185static struct timeval begin, end;
186
187/*
188 * startTimer: call where you want to start timing
189 */
190static void
191startTimer(void)
192{
193 gettimeofday(&begin, NULL);
194}
195
196/*
197 * endTimer: call where you want to stop timing and to print out a
198 * message about the timing performed; format is a printf
199 * type argument
200 */
201static void
Daniel Veillard118aed72002-09-24 14:13:13 +0000202endTimer(const char *fmt, ...)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000203{
204 long msec;
205 va_list ap;
206
207 gettimeofday(&end, NULL);
208 msec = end.tv_sec - begin.tv_sec;
209 msec *= 1000;
210 msec += (end.tv_usec - begin.tv_usec) / 1000;
211
212#ifndef HAVE_STDARG_H
213#error "endTimer required stdarg functions"
214#endif
Daniel Veillard118aed72002-09-24 14:13:13 +0000215 va_start(ap, fmt);
216 vfprintf(stderr, fmt, ap);
Daniel Veillard01db67c2001-12-18 07:09:59 +0000217 va_end(ap);
218
219 fprintf(stderr, " took %ld ms\n", msec);
220}
221#elif defined(HAVE_TIME_H)
Daniel Veillard01db67c2001-12-18 07:09:59 +0000222/*
223 * No gettimeofday function, so we have to make do with calling clock.
224 * This is obviously less accurate, but there's little we can do about
225 * that.
226 */
Daniel Veillard90bc3712002-03-07 15:12:58 +0000227#ifndef CLOCKS_PER_SEC
228#define CLOCKS_PER_SEC 100
229#endif
Daniel Veillard01db67c2001-12-18 07:09:59 +0000230
231static clock_t begin, end;
232static void
233startTimer(void)
234{
235 begin = clock();
236}
237static void
238endTimer(const char *fmt, ...)
239{
240 long msec;
241 va_list ap;
242
243 end = clock();
244 msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
245
246#ifndef HAVE_STDARG_H
247#error "endTimer required stdarg functions"
248#endif
249 va_start(ap, fmt);
250 vfprintf(stderr, fmt, ap);
251 va_end(ap);
252 fprintf(stderr, " took %ld ms\n", msec);
253}
254#else
255
256/*
257 * We don't have a gettimeofday or time.h, so we just don't do timing
258 */
259static void
260startTimer(void)
261{
262 /*
263 * Do nothing
264 */
265}
266static void
267endTimer(char *format, ...)
268{
269 /*
270 * We cannot do anything because we don't have a timing function
271 */
272#ifdef HAVE_STDARG_H
273 va_start(ap, format);
274 vfprintf(stderr, format, ap);
275 va_end(ap);
276 fprintf(stderr, " was not timed\n", msec);
277#else
278 /* We don't have gettimeofday, time or stdarg.h, what crazy world is
279 * this ?!
280 */
281#endif
282}
283#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000284/************************************************************************
285 * *
286 * HTML ouput *
287 * *
288 ************************************************************************/
289char buffer[50000];
290
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000291static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000292xmlHTMLEncodeSend(void) {
293 char *result;
294
295 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
296 if (result) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000297 xmlGenericError(xmlGenericErrorContext, "%s", result);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000298 xmlFree(result);
299 }
300 buffer[0] = 0;
301}
302
303/**
304 * xmlHTMLPrintFileInfo:
305 * @input: an xmlParserInputPtr input
306 *
307 * Displays the associated file and line informations for the current input
308 */
309
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000310static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000311xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000312 int len;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000313 xmlGenericError(xmlGenericErrorContext, "<p>");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000314
315 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000316 if (input != NULL) {
317 if (input->filename) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000318 snprintf(&buffer[len], sizeof(buffer) - len, "%s:%d: ", input->filename,
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000319 input->line);
320 } else {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000321 snprintf(&buffer[len], sizeof(buffer) - len, "Entity: line %d: ", input->line);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000322 }
323 }
324 xmlHTMLEncodeSend();
325}
326
327/**
328 * xmlHTMLPrintFileContext:
329 * @input: an xmlParserInputPtr input
330 *
331 * Displays current context within the input content for error tracking
332 */
333
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000334static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000335xmlHTMLPrintFileContext(xmlParserInputPtr input) {
336 const xmlChar *cur, *base;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000337 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000338 int n;
339
340 if (input == NULL) return;
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000341 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000342 cur = input->cur;
343 base = input->base;
344 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
345 cur--;
346 }
347 n = 0;
348 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
349 cur--;
350 if ((*cur == '\n') || (*cur == '\r')) cur++;
351 base = cur;
352 n = 0;
353 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000354 len = strlen(buffer);
355 snprintf(&buffer[len], sizeof(buffer) - len, "%c",
356 (unsigned char) *cur++);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000357 n++;
358 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000359 len = strlen(buffer);
360 snprintf(&buffer[len], sizeof(buffer) - len, "\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000361 cur = input->cur;
362 while ((*cur == '\n') || (*cur == '\r'))
363 cur--;
364 n = 0;
365 while ((cur != base) && (n++ < 80)) {
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000366 len = strlen(buffer);
367 snprintf(&buffer[len], sizeof(buffer) - len, " ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000368 base++;
369 }
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000370 len = strlen(buffer);
371 snprintf(&buffer[len], sizeof(buffer) - len, "^\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000372 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000373 xmlGenericError(xmlGenericErrorContext, "</pre>");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000374}
375
376/**
377 * xmlHTMLError:
378 * @ctx: an XML parser context
379 * @msg: the message to display/transmit
380 * @...: extra parameters for the message display
381 *
382 * Display and format an error messages, gives file, line, position and
383 * extra parameters.
384 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000385static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000386xmlHTMLError(void *ctx, const char *msg, ...)
387{
388 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
389 xmlParserInputPtr input;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000390 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000391 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000392
393 buffer[0] = 0;
394 input = ctxt->input;
395 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000396 input = ctxt->inputTab[ctxt->inputNr - 2];
397 }
398
399 xmlHTMLPrintFileInfo(input);
400
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000401 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000402 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000403 len = strlen(buffer);
404 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000405 va_end(args);
406 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000407 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000408
409 xmlHTMLPrintFileContext(input);
410 xmlHTMLEncodeSend();
411}
412
413/**
414 * xmlHTMLWarning:
415 * @ctx: an XML parser context
416 * @msg: the message to display/transmit
417 * @...: extra parameters for the message display
418 *
419 * Display and format a warning messages, gives file, line, position and
420 * extra parameters.
421 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000422static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000423xmlHTMLWarning(void *ctx, const char *msg, ...)
424{
425 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
426 xmlParserInputPtr input;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000427 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000428 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000429
430 buffer[0] = 0;
431 input = ctxt->input;
432 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000433 input = ctxt->inputTab[ctxt->inputNr - 2];
434 }
435
436
437 xmlHTMLPrintFileInfo(input);
438
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000439 xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000440 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000441 len = strlen(buffer);
442 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000443 va_end(args);
444 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000445 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000446
447 xmlHTMLPrintFileContext(input);
448 xmlHTMLEncodeSend();
449}
450
451/**
452 * xmlHTMLValidityError:
453 * @ctx: an XML parser context
454 * @msg: the message to display/transmit
455 * @...: extra parameters for the message display
456 *
457 * Display and format an validity error messages, gives file,
458 * line, position and extra parameters.
459 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000460static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000461xmlHTMLValidityError(void *ctx, const char *msg, ...)
462{
463 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
464 xmlParserInputPtr input;
465 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000466 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000467
468 buffer[0] = 0;
469 input = ctxt->input;
470 if ((input->filename == NULL) && (ctxt->inputNr > 1))
471 input = ctxt->inputTab[ctxt->inputNr - 2];
472
473 xmlHTMLPrintFileInfo(input);
474
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000475 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000476 len = strlen(buffer);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000477 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000478 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000479 va_end(args);
480 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000481 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000482
483 xmlHTMLPrintFileContext(input);
484 xmlHTMLEncodeSend();
485}
486
487/**
488 * xmlHTMLValidityWarning:
489 * @ctx: an XML parser context
490 * @msg: the message to display/transmit
491 * @...: extra parameters for the message display
492 *
493 * Display and format a validity warning messages, gives file, line,
494 * position and extra parameters.
495 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000496static void
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000497xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
498{
499 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
500 xmlParserInputPtr input;
501 va_list args;
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000502 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000503
504 buffer[0] = 0;
505 input = ctxt->input;
506 if ((input->filename == NULL) && (ctxt->inputNr > 1))
507 input = ctxt->inputTab[ctxt->inputNr - 2];
508
509 xmlHTMLPrintFileInfo(input);
510
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000511 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000512 va_start(args, msg);
Aleksey Sanin49cc9752002-06-14 17:07:10 +0000513 len = strlen(buffer);
514 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000515 va_end(args);
516 xmlHTMLEncodeSend();
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +0000517 xmlGenericError(xmlGenericErrorContext, "</p>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000518
519 xmlHTMLPrintFileContext(input);
520 xmlHTMLEncodeSend();
521}
522
523/************************************************************************
524 * *
525 * Shell Interface *
526 * *
527 ************************************************************************/
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000528#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000529/**
530 * xmlShellReadline:
531 * @prompt: the prompt value
532 *
533 * Read a string
534 *
535 * Returns a pointer to it or NULL on EOF the caller is expected to
536 * free the returned string.
537 */
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000538static char *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000539xmlShellReadline(char *prompt) {
540#ifdef HAVE_LIBREADLINE
541 char *line_read;
542
543 /* Get a line from the user. */
544 line_read = readline (prompt);
545
546 /* If the line has any text in it, save it on the history. */
547 if (line_read && *line_read)
548 add_history (line_read);
549
550 return (line_read);
551#else
552 char line_read[501];
Daniel Veillard29e43992001-12-13 22:21:58 +0000553 char *ret;
554 int len;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000555
556 if (prompt != NULL)
557 fprintf(stdout, "%s", prompt);
558 if (!fgets(line_read, 500, stdin))
559 return(NULL);
560 line_read[500] = 0;
Daniel Veillard29e43992001-12-13 22:21:58 +0000561 len = strlen(line_read);
562 ret = (char *) malloc(len + 1);
563 if (ret != NULL) {
564 memcpy (ret, line_read, len + 1);
565 }
566 return(ret);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000567#endif
568}
Daniel Veillard56ada1d2003-01-07 11:17:25 +0000569#endif /* LIBXML_DEBUG_ENABLED */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000570
571/************************************************************************
572 * *
Daniel Veillard5e873c42000-04-12 13:27:38 +0000573 * I/O Interfaces *
574 * *
575 ************************************************************************/
576
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000577static int myRead(FILE *f, char * buf, int len) {
578 return(fread(buf, 1, len, f));
Daniel Veillard5e873c42000-04-12 13:27:38 +0000579}
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000580static void myClose(FILE *f) {
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000581 if (f != stdin) {
Daniel Veillard5e873c42000-04-12 13:27:38 +0000582 fclose(f);
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000583 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000584}
585
586/************************************************************************
587 * *
Daniel Veillard7704fb12003-01-03 16:19:51 +0000588 * Stream Test processing *
589 * *
590 ************************************************************************/
Daniel Veillard7704fb12003-01-03 16:19:51 +0000591static void processNode(xmlTextReaderPtr reader) {
Daniel Veillarde59494f2003-01-04 16:35:29 +0000592 xmlChar *name, *value;
Daniel Veillard7704fb12003-01-03 16:19:51 +0000593
Daniel Veillarde59494f2003-01-04 16:35:29 +0000594 name = xmlTextReaderName(reader);
595 if (name == NULL)
596 name = xmlStrdup(BAD_CAST "--");
Daniel Veillard99737f52003-03-22 14:55:50 +0000597
Daniel Veillarde59494f2003-01-04 16:35:29 +0000598 value = xmlTextReaderValue(reader);
Daniel Veillard7704fb12003-01-03 16:19:51 +0000599
Daniel Veillard99737f52003-03-22 14:55:50 +0000600 printf("%d %d %s %d %d",
Daniel Veillarde59494f2003-01-04 16:35:29 +0000601 xmlTextReaderDepth(reader),
602 xmlTextReaderNodeType(reader),
603 name,
Daniel Veillard99737f52003-03-22 14:55:50 +0000604 xmlTextReaderIsEmptyElement(reader),
605 xmlTextReaderHasValue(reader));
Daniel Veillarde59494f2003-01-04 16:35:29 +0000606 xmlFree(name);
607 if (value == NULL)
608 printf("\n");
609 else {
610 printf(" %s\n", value);
611 xmlFree(value);
Daniel Veillard7704fb12003-01-03 16:19:51 +0000612 }
613}
614
615static void streamFile(char *filename) {
616 xmlTextReaderPtr reader;
617 int ret;
618
Daniel Veillard7704fb12003-01-03 16:19:51 +0000619 reader = xmlNewTextReaderFilename(filename);
620 if (reader != NULL) {
621 if (valid)
622 xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
Daniel Veillardce192eb2003-04-16 15:58:05 +0000623 else
624 xmlTextReaderSetParserProp(reader, XML_PARSER_LOADDTD, 1);
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000625#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +0000626 if (relaxng != NULL) {
627 if (timing) {
628 startTimer();
629 }
630 ret = xmlTextReaderRelaxNGValidate(reader, relaxng);
631 if (ret < 0) {
632 xmlGenericError(xmlGenericErrorContext,
633 "Relax-NG schema %s failed to compile\n", relaxng);
634 relaxng = NULL;
635 }
636 if (timing) {
637 endTimer("Compiling the schemas");
638 }
639 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000640#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +0000641
642 /*
643 * Process all nodes in sequence
644 */
Daniel Veillardce192eb2003-04-16 15:58:05 +0000645 if (timing) {
646 startTimer();
647 }
Daniel Veillard7704fb12003-01-03 16:19:51 +0000648 ret = xmlTextReaderRead(reader);
649 while (ret == 1) {
650 if (debug)
651 processNode(reader);
652 ret = xmlTextReaderRead(reader);
653 }
Daniel Veillardce192eb2003-04-16 15:58:05 +0000654 if (timing) {
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000655#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +0000656 if ((valid) || (relaxng != NULL))
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000657#else
658 if (valid)
659#endif
Daniel Veillardce192eb2003-04-16 15:58:05 +0000660 endTimer("Parsing and validating");
661 else
662 endTimer("Parsing");
663 }
Daniel Veillard7704fb12003-01-03 16:19:51 +0000664
Daniel Veillardf6bad792003-04-11 19:38:54 +0000665 if (valid) {
666 if (xmlTextReaderIsValid(reader) != 1) {
667 xmlGenericError(xmlGenericErrorContext,
668 "Document %s does not validate\n", filename);
669 progresult = 3;
670 }
671 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000672#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardf4e55762003-04-15 23:32:22 +0000673 if (relaxng != NULL) {
674 if (xmlTextReaderIsValid(reader) != 1) {
675 printf("%s fails to validate\n", filename);
676 progresult = 3;
677 } else {
678 printf("%s validates\n", filename);
679 }
680 }
Daniel Veillard37fc84d2003-05-09 19:38:15 +0000681#endif
Daniel Veillard7704fb12003-01-03 16:19:51 +0000682 /*
683 * Done, cleanup and status
684 */
685 xmlFreeTextReader(reader);
686 if (ret != 0) {
687 printf("%s : failed to parse\n", filename);
Daniel Veillardf6bad792003-04-11 19:38:54 +0000688 progresult = 1;
Daniel Veillard7704fb12003-01-03 16:19:51 +0000689 }
690 } else {
691 fprintf(stderr, "Unable to open %s\n", filename);
Daniel Veillardf6bad792003-04-11 19:38:54 +0000692 progresult = 1;
Daniel Veillard7704fb12003-01-03 16:19:51 +0000693 }
694}
695
696/************************************************************************
697 * *
698 * Tree Test processing *
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000699 * *
700 ************************************************************************/
Daniel Veillard56a4cb82001-03-24 17:00:36 +0000701static void parseAndPrintFile(char *filename) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000702 xmlDocPtr doc = NULL, tmp;
703
Daniel Veillard48b2f892001-02-25 16:11:03 +0000704 if ((timing) && (!repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +0000705 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +0000706
707
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000708 if (filename == NULL) {
709 if (generate) {
710 xmlNodePtr n;
711
712 doc = xmlNewDoc(BAD_CAST "1.0");
713 n = xmlNewNode(NULL, BAD_CAST "info");
714 xmlNodeSetContent(n, BAD_CAST "abc");
715 xmlDocSetRootElement(doc, n);
716 }
717 }
Daniel Veillard89cad532001-10-22 09:46:13 +0000718#ifdef LIBXML_DOCB_ENABLED
719 /*
720 * build an SGML tree from a string;
721 */
722 else if ((sgml) && (push)) {
723 FILE *f;
724
725 f = fopen(filename, "r");
726 if (f != NULL) {
727 int res, size = 3;
728 char chars[4096];
729 docbParserCtxtPtr ctxt;
730
731 /* if (repeat) */
732 size = 4096;
733 res = fread(chars, 1, 4, f);
734 if (res > 0) {
735 ctxt = docbCreatePushParserCtxt(NULL, NULL,
William M. Brack779af002003-08-01 15:55:39 +0000736 chars, res, filename, XML_CHAR_ENCODING_NONE);
Daniel Veillard89cad532001-10-22 09:46:13 +0000737 while ((res = fread(chars, 1, size, f)) > 0) {
738 docbParseChunk(ctxt, chars, res, 0);
739 }
740 docbParseChunk(ctxt, chars, 0, 1);
741 doc = ctxt->myDoc;
742 docbFreeParserCtxt(ctxt);
743 }
744 fclose(f);
745 }
746 } else if (sgml) {
747 doc = docbParseFile(filename, NULL);
748 }
749#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000750#ifdef LIBXML_HTML_ENABLED
William M. Brack78637da2003-07-31 14:47:38 +0000751 else if ((html) && (push)) {
752 FILE *f;
753
754 f = fopen(filename, "r");
755 if (f != NULL) {
756 int res, size = 3;
757 char chars[4096];
758 htmlParserCtxtPtr ctxt;
759
760 /* if (repeat) */
761 size = 4096;
762 res = fread(chars, 1, 4, f);
763 if (res > 0) {
764 ctxt = htmlCreatePushParserCtxt(NULL, NULL,
765 chars, res, filename, 0);
766 while ((res = fread(chars, 1, size, f)) > 0) {
767 htmlParseChunk(ctxt, chars, res, 0);
768 }
769 htmlParseChunk(ctxt, chars, 0, 1);
770 doc = ctxt->myDoc;
771 htmlFreeParserCtxt(ctxt);
772 }
773 fclose(f);
774 }
775 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000776 else if (html) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000777 doc = htmlParseFile(filename, NULL);
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000778 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000779#endif /* LIBXML_HTML_ENABLED */
Daniel Veillardd2f3ec72001-04-11 07:50:02 +0000780 else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000781 /*
782 * build an XML tree from a string;
783 */
784 if (push) {
785 FILE *f;
786
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000787 /* '-' Usually means stdin -<sven@zen.org> */
788 if ((filename[0] == '-') && (filename[1] == 0)) {
789 f = stdin;
790 } else {
791 f = fopen(filename, "r");
792 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000793 if (f != NULL) {
Daniel Veillarde715dd22000-08-29 18:29:38 +0000794 int ret;
Daniel Veillarda880b122003-04-21 21:36:41 +0000795 int res, size = 1024;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000796 char chars[1024];
797 xmlParserCtxtPtr ctxt;
798
Daniel Veillarda880b122003-04-21 21:36:41 +0000799 /* if (repeat) size = 1024; */
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000800 res = fread(chars, 1, 4, f);
801 if (res > 0) {
802 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
803 chars, res, filename);
804 while ((res = fread(chars, 1, size, f)) > 0) {
805 xmlParseChunk(ctxt, chars, res, 0);
806 }
807 xmlParseChunk(ctxt, chars, 0, 1);
808 doc = ctxt->myDoc;
Daniel Veillarde715dd22000-08-29 18:29:38 +0000809 ret = ctxt->wellFormed;
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000810 xmlFreeParserCtxt(ctxt);
Daniel Veillarde715dd22000-08-29 18:29:38 +0000811 if (!ret) {
812 xmlFreeDoc(doc);
813 doc = NULL;
814 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000815 }
816 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000817 } else if (testIO) {
818 int ret;
819 FILE *f;
820
Daniel Veillard4a6845d2001-01-03 13:32:39 +0000821 /* '-' Usually means stdin -<sven@zen.org> */
822 if ((filename[0] == '-') && (filename[1] == 0)) {
823 f = stdin;
824 } else {
825 f = fopen(filename, "r");
826 }
Daniel Veillard5e873c42000-04-12 13:27:38 +0000827 if (f != NULL) {
828 xmlParserCtxtPtr ctxt;
829
830 ctxt = xmlCreateIOParserCtxt(NULL, NULL,
831 (xmlInputReadCallback) myRead,
832 (xmlInputCloseCallback) myClose,
833 f, XML_CHAR_ENCODING_NONE);
834 xmlParseDocument(ctxt);
835
836 ret = ctxt->wellFormed;
837 doc = ctxt->myDoc;
838 xmlFreeParserCtxt(ctxt);
839 if (!ret) {
840 xmlFreeDoc(doc);
841 doc = NULL;
842 }
843 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000844 } else if (recovery) {
845 doc = xmlRecoverFile(filename);
846 } else if (htmlout) {
847 int ret;
848 xmlParserCtxtPtr ctxt;
849 xmlSAXHandler silent, *old;
850
851 ctxt = xmlCreateFileParserCtxt(filename);
Daniel Veillard88a172f2000-08-04 18:23:10 +0000852
853 if (ctxt == NULL) {
Daniel Veillardcbaf3992001-12-31 16:16:02 +0000854 /* If xmlCreateFileParserCtxt() return NULL something
Daniel Veillard88a172f2000-08-04 18:23:10 +0000855 strange happened so we don't want to do anything. Do
856 we want to print an error message here?
857 <sven@zen.org> */
Daniel Veillard7ebb1ee2000-08-04 18:24:45 +0000858 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000859 } else {
860 memcpy(&silent, ctxt->sax, sizeof(silent));
861 old = ctxt->sax;
862 silent.error = xmlHTMLError;
863 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000864 silent.warning = xmlHTMLWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000865 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000866 silent.warning = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000867 silent.fatalError = xmlHTMLError;
868 ctxt->sax = &silent;
869 ctxt->vctxt.error = xmlHTMLValidityError;
870 if (xmlGetWarningsDefaultValue)
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000871 ctxt->vctxt.warning = xmlHTMLValidityWarning;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000872 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000873 ctxt->vctxt.warning = NULL;
874
Daniel Veillard88a172f2000-08-04 18:23:10 +0000875 xmlParseDocument(ctxt);
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000876
Daniel Veillard88a172f2000-08-04 18:23:10 +0000877 ret = ctxt->wellFormed;
878 doc = ctxt->myDoc;
879 ctxt->sax = old;
880 xmlFreeParserCtxt(ctxt);
881 if (!ret) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000882 xmlFreeDoc(doc);
883 doc = NULL;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000884 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000885 }
Daniel Veillard46e370e2000-07-21 20:32:03 +0000886#ifdef HAVE_SYS_MMAN_H
887 } else if (memory) {
888 int fd;
889 struct stat info;
890 const char *base;
891 if (stat(filename, &info) < 0)
892 return;
893 if ((fd = open(filename, O_RDONLY)) < 0)
894 return;
895 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Daniel Veillard29579362000-08-14 17:57:48 +0000896 if (base == (void *) MAP_FAILED)
Daniel Veillard46e370e2000-07-21 20:32:03 +0000897 return;
898
899 doc = xmlParseMemory((char *) base, info.st_size);
900 munmap((char *) base, info.st_size);
901#endif
Daniel Veillardea7751d2002-12-20 00:16:24 +0000902 } else if (valid) {
903 int ret;
904 xmlParserCtxtPtr ctxt;
905
906 ctxt = xmlCreateFileParserCtxt(filename);
907
908 if (ctxt == NULL) {
909 doc = NULL;
910 } else {
911 xmlParseDocument(ctxt);
912 if (ctxt->valid == 0)
913 progresult = 4;
914 ret = ctxt->wellFormed;
915 doc = ctxt->myDoc;
916 xmlFreeParserCtxt(ctxt);
917 if (!ret) {
918 xmlFreeDoc(doc);
919 doc = NULL;
920 }
921 }
922 } else {
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000923 doc = xmlParseFile(filename);
Daniel Veillardea7751d2002-12-20 00:16:24 +0000924 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000925 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000926
Daniel Veillard88a172f2000-08-04 18:23:10 +0000927 /*
928 * If we don't have a document we might as well give up. Do we
929 * want an error message here? <sven@zen.org> */
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000930 if (doc == NULL) {
Daniel Veillardf7cd4812001-02-23 18:44:52 +0000931 progresult = 1;
Daniel Veillard88a172f2000-08-04 18:23:10 +0000932 return;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000933 }
934
Daniel Veillard48b2f892001-02-25 16:11:03 +0000935 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +0000936 endTimer("Parsing");
Daniel Veillard48b2f892001-02-25 16:11:03 +0000937 }
938
Daniel Veillard29e43992001-12-13 22:21:58 +0000939 /*
940 * Remove DOCTYPE nodes
941 */
942 if (dropdtd) {
943 xmlDtdPtr dtd;
944
945 dtd = xmlGetIntSubset(doc);
946 if (dtd != NULL) {
947 xmlUnlinkNode((xmlNodePtr)dtd);
948 xmlFreeDtd(dtd);
949 }
950 }
951
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000952#ifdef LIBXML_XINCLUDE_ENABLED
Daniel Veillard48b2f892001-02-25 16:11:03 +0000953 if (xinclude) {
954 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +0000955 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +0000956 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000957 xmlXIncludeProcess(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +0000958 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +0000959 endTimer("Xinclude processing");
Daniel Veillard48b2f892001-02-25 16:11:03 +0000960 }
961 }
Daniel Veillard9e8bfae2000-11-06 16:43:11 +0000962#endif
Daniel Veillard88a172f2000-08-04 18:23:10 +0000963
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000964#ifdef LIBXML_DEBUG_ENABLED
965 /*
Daniel Veillardcbaf3992001-12-31 16:16:02 +0000966 * shell interaction
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000967 */
968 if (shell)
969 xmlShell(doc, filename, xmlShellReadline, stdout);
970#endif
971
972 /*
973 * test intermediate copy if needed.
974 */
975 if (copy) {
976 tmp = doc;
977 doc = xmlCopyDoc(doc, 1);
978 xmlFreeDoc(tmp);
979 }
980
981 if ((insert) && (!html)) {
982 const xmlChar* list[256];
983 int nb, i;
984 xmlNodePtr node;
985
986 if (doc->children != NULL) {
987 node = doc->children;
988 while ((node != NULL) && (node->last == NULL)) node = node->next;
989 if (node != NULL) {
990 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
991 if (nb < 0) {
992 printf("could not get valid list of elements\n");
993 } else if (nb == 0) {
MDT 2001 John Fleckbbb9e432001-09-24 03:08:43 +0000994 printf("No element can be inserted under root\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000995 } else {
MDT 2001 John Fleckbbb9e432001-09-24 03:08:43 +0000996 printf("%d element types can be inserted under root:\n",
Daniel Veillardce8b83b2000-04-05 18:38:42 +0000997 nb);
998 for (i = 0;i < nb;i++) {
Daniel Veillard8a1b1852003-01-05 22:37:17 +0000999 printf("%s\n", (char *) list[i]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001000 }
1001 }
1002 }
1003 }
1004 }else if (noout == 0) {
1005 /*
1006 * print it.
1007 */
1008#ifdef LIBXML_DEBUG_ENABLED
1009 if (!debug) {
1010#endif
Daniel Veillard48b2f892001-02-25 16:11:03 +00001011 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001012 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001013 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +00001014#ifdef HAVE_SYS_MMAN_H
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001015 if (memory) {
1016 xmlChar *result;
1017 int len;
1018
1019 if (encoding != NULL) {
Daniel Veillardd536f702001-11-08 17:32:47 +00001020 if ( format ) {
1021 xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
1022 } else {
1023 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
1024 }
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001025 } else {
Daniel Veillard90493a92001-08-14 14:12:47 +00001026 if (format)
1027 xmlDocDumpFormatMemory(doc, &result, &len, 1);
1028 else
1029 xmlDocDumpMemory(doc, &result, &len);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001030 }
1031 if (result == NULL) {
1032 fprintf(stderr, "Failed to save\n");
1033 } else {
1034 write(1, result, len);
1035 xmlFree(result);
1036 }
Daniel Veillard3b2c2612001-04-04 00:09:00 +00001037 } else
1038#endif /* HAVE_SYS_MMAN_H */
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001039 if (compress) {
1040 xmlSaveFile(output ? output : "-", doc);
1041 }
Daniel Veillardd536f702001-11-08 17:32:47 +00001042 else if (encoding != NULL) {
1043 if ( format ) {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001044 xmlSaveFormatFileEnc(output ? output : "-", doc, encoding, 1);
1045 }
Daniel Veillardd536f702001-11-08 17:32:47 +00001046 else {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001047 xmlSaveFileEnc(output ? output : "-", doc, encoding);
Daniel Veillardd536f702001-11-08 17:32:47 +00001048 }
1049 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001050 else if (format) {
1051 xmlSaveFormatFile(output ? output : "-", doc, 1);
1052 }
1053 else {
1054 FILE *out;
1055 if (output == NULL)
1056 out = stdout;
1057 else {
1058 out = fopen(output,"wb");
1059 }
1060 xmlDocDump(out, doc);
1061
1062 if (output)
1063 fclose(out);
1064 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001065 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001066 endTimer("Saving");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001067 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001068#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001069 } else {
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001070 FILE *out;
1071 if (output == NULL)
1072 out = stdout;
1073 else {
1074 out = fopen(output,"wb");
1075 }
1076 xmlDebugDumpDocument(out, doc);
1077
1078 if (output)
1079 fclose(out);
Daniel Veillarda6d8eb62000-12-27 10:46:47 +00001080 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001081#endif
1082 }
1083
1084 /*
1085 * A posteriori validation test
1086 */
Daniel Veillard66f68e72003-08-18 16:39:51 +00001087 if ((dtdvalid != NULL) || (dtdvalidfpi != NULL)) {
Daniel Veillardcd429612000-10-11 15:57:05 +00001088 xmlDtdPtr dtd;
1089
Daniel Veillard48b2f892001-02-25 16:11:03 +00001090 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001091 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001092 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00001093 if (dtdvalid != NULL)
1094 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
1095 else
1096 dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL);
Daniel Veillard48b2f892001-02-25 16:11:03 +00001097 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001098 endTimer("Parsing DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001099 }
Daniel Veillardcd429612000-10-11 15:57:05 +00001100 if (dtd == NULL) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00001101 if (dtdvalid != NULL)
1102 xmlGenericError(xmlGenericErrorContext,
1103 "Could not parse DTD %s\n", dtdvalid);
1104 else
1105 xmlGenericError(xmlGenericErrorContext,
1106 "Could not parse DTD %s\n", dtdvalidfpi);
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001107 progresult = 2;
Daniel Veillardcd429612000-10-11 15:57:05 +00001108 } else {
Daniel Veillarda37aab82003-06-09 09:10:36 +00001109 xmlValidCtxtPtr cvp;
1110
1111 if ((cvp = xmlNewValidCtxt()) == NULL) {
1112 xmlGenericError(xmlGenericErrorContext,
1113 "Couldn't allocate validation context\n");
1114 exit(-1);
1115 }
1116 cvp->userData = (void *) stderr;
1117 cvp->error = (xmlValidityErrorFunc) fprintf;
1118 cvp->warning = (xmlValidityWarningFunc) fprintf;
1119
Daniel Veillard48b2f892001-02-25 16:11:03 +00001120 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001121 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001122 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00001123 if (!xmlValidateDtd(cvp, doc, dtd)) {
Daniel Veillard66f68e72003-08-18 16:39:51 +00001124 if (dtdvalid != NULL)
1125 xmlGenericError(xmlGenericErrorContext,
1126 "Document %s does not validate against %s\n",
1127 filename, dtdvalid);
1128 else
1129 xmlGenericError(xmlGenericErrorContext,
1130 "Document %s does not validate against %s\n",
1131 filename, dtdvalidfpi);
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001132 progresult = 3;
Daniel Veillardcd429612000-10-11 15:57:05 +00001133 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001134 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001135 endTimer("Validating against DTD");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001136 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00001137 xmlFreeValidCtxt(cvp);
Daniel Veillardcd429612000-10-11 15:57:05 +00001138 xmlFreeDtd(dtd);
1139 }
1140 } else if (postvalid) {
Daniel Veillarda37aab82003-06-09 09:10:36 +00001141 xmlValidCtxtPtr cvp;
1142
1143 if ((cvp = xmlNewValidCtxt()) == NULL) {
1144 xmlGenericError(xmlGenericErrorContext,
1145 "Couldn't allocate validation context\n");
1146 exit(-1);
1147 }
1148
Daniel Veillard48b2f892001-02-25 16:11:03 +00001149 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001150 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001151 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00001152 cvp->userData = (void *) stderr;
1153 cvp->error = (xmlValidityErrorFunc) fprintf;
1154 cvp->warning = (xmlValidityWarningFunc) fprintf;
1155 if (!xmlValidateDocument(cvp, doc)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001156 xmlGenericError(xmlGenericErrorContext,
1157 "Document %s does not validate\n", filename);
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001158 progresult = 3;
Daniel Veillardcd429612000-10-11 15:57:05 +00001159 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001160 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001161 endTimer("Validating");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001162 }
Daniel Veillarda37aab82003-06-09 09:10:36 +00001163 xmlFreeValidCtxt(cvp);
Daniel Veillard71531f32003-02-05 13:19:53 +00001164#ifdef LIBXML_SCHEMAS_ENABLED
1165 } else if (relaxngschemas != NULL) {
1166 xmlRelaxNGValidCtxtPtr ctxt;
1167 int ret;
1168
Daniel Veillard42f12e92003-03-07 18:32:59 +00001169 if ((timing) && (!repeat)) {
1170 startTimer();
1171 }
1172
Daniel Veillard71531f32003-02-05 13:19:53 +00001173 ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
1174 xmlRelaxNGSetValidErrors(ctxt,
1175 (xmlRelaxNGValidityErrorFunc) fprintf,
1176 (xmlRelaxNGValidityWarningFunc) fprintf,
1177 stderr);
1178 ret = xmlRelaxNGValidateDoc(ctxt, doc);
1179 if (ret == 0) {
1180 printf("%s validates\n", filename);
1181 } else if (ret > 0) {
1182 printf("%s fails to validate\n", filename);
1183 } else {
1184 printf("%s validation generated an internal error\n",
1185 filename);
1186 }
1187 xmlRelaxNGFreeValidCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00001188 if ((timing) && (!repeat)) {
1189 endTimer("Validating");
1190 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001191 } else if (wxschemas != NULL) {
1192 xmlSchemaValidCtxtPtr ctxt;
1193 int ret;
1194
1195 if ((timing) && (!repeat)) {
1196 startTimer();
1197 }
1198
1199 ctxt = xmlSchemaNewValidCtxt(wxschemas);
1200 xmlSchemaSetValidErrors(ctxt,
1201 (xmlSchemaValidityErrorFunc) fprintf,
1202 (xmlSchemaValidityWarningFunc) fprintf,
1203 stderr);
1204 ret = xmlSchemaValidateDoc(ctxt, doc);
1205 if (ret == 0) {
1206 printf("%s validates\n", filename);
1207 } else if (ret > 0) {
1208 printf("%s fails to validate\n", filename);
1209 } else {
1210 printf("%s validation generated an internal error\n",
1211 filename);
1212 }
1213 xmlSchemaFreeValidCtxt(ctxt);
1214 if ((timing) && (!repeat)) {
1215 endTimer("Validating");
1216 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001217#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001218 }
1219
1220#ifdef LIBXML_DEBUG_ENABLED
1221 if ((debugent) && (!html))
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001222 xmlDebugDumpEntities(stderr, doc);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001223#endif
1224
1225 /*
1226 * free it.
1227 */
Daniel Veillard48b2f892001-02-25 16:11:03 +00001228 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001229 startTimer();
Daniel Veillard48b2f892001-02-25 16:11:03 +00001230 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001231 xmlFreeDoc(doc);
Daniel Veillard48b2f892001-02-25 16:11:03 +00001232 if ((timing) && (!repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001233 endTimer("Freeing");
Daniel Veillard48b2f892001-02-25 16:11:03 +00001234 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001235}
1236
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001237/************************************************************************
1238 * *
1239 * Usage and Main *
1240 * *
1241 ************************************************************************/
1242
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00001243static void showVersion(const char *name) {
1244 fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
1245 fprintf(stderr, " compiled with: ");
1246#ifdef LIBXML_FTP_ENABLED
1247 fprintf(stderr, "FTP ");
1248#endif
1249#ifdef LIBXML_HTTP_ENABLED
1250 fprintf(stderr, "HTTP ");
1251#endif
1252#ifdef LIBXML_HTML_ENABLED
1253 fprintf(stderr, "HTML ");
1254#endif
1255#ifdef LIBXML_C14N_ENABLED
1256 fprintf(stderr, "C14N ");
1257#endif
1258#ifdef LIBXML_CATALOG_ENABLED
1259 fprintf(stderr, "Catalog ");
1260#endif
1261#ifdef LIBXML_DOCB_ENABLED
1262 fprintf(stderr, "DocBook ");
1263#endif
1264#ifdef LIBXML_XPATH_ENABLED
1265 fprintf(stderr, "XPath ");
1266#endif
1267#ifdef LIBXML_XPTR_ENABLED
1268 fprintf(stderr, "XPointer ");
1269#endif
1270#ifdef LIBXML_XINCLUDE_ENABLED
1271 fprintf(stderr, "XInclude ");
1272#endif
1273#ifdef LIBXML_ICONV_ENABLED
1274 fprintf(stderr, "Iconv ");
1275#endif
1276#ifdef DEBUG_MEMORY_LOCATION
1277 fprintf(stderr, "MemDebug ");
1278#endif
1279#ifdef LIBXML_UNICODE_ENABLED
1280 fprintf(stderr, "Unicode ");
1281#endif
1282#ifdef LIBXML_REGEXP_ENABLED
1283 fprintf(stderr, "Regexps ");
1284#endif
1285#ifdef LIBXML_AUTOMATA_ENABLED
1286 fprintf(stderr, "Automata ");
1287#endif
1288#ifdef LIBXML_SCHEMAS_ENABLED
1289 fprintf(stderr, "Schemas ");
1290#endif
1291 fprintf(stderr, "\n");
1292}
1293
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001294static void usage(const char *name) {
1295 printf("Usage : %s [options] XMLfiles ...\n", name);
1296 printf("\tParse the XML files and output the result of the parsing\n");
1297 printf("\t--version : display the version of the XML library used\n");
1298#ifdef LIBXML_DEBUG_ENABLED
1299 printf("\t--debug : dump a debug tree of the in-memory document\n");
1300 printf("\t--shell : run a navigating shell\n");
1301 printf("\t--debugent : debug the entities defined in the document\n");
Daniel Veillard8326e732003-01-07 00:19:07 +00001302#else
1303 printf("\t--debug : dump the nodes content when using --stream\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001304#endif
1305 printf("\t--copy : used to test the internal copy implementation\n");
1306 printf("\t--recover : output what was parsable on broken XML documents\n");
1307 printf("\t--noent : substitute entity references by their value\n");
1308 printf("\t--noout : don't output the result tree\n");
Daniel Veillarde8b09e42003-05-13 22:14:13 +00001309 printf("\t--nonet : refuse to fetch DTDs or entities over network\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001310 printf("\t--htmlout : output results as HTML\n");
Daniel Veillard05c13a22001-09-09 08:38:09 +00001311 printf("\t--nowrap : do not put HTML doc wrapper\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001312 printf("\t--valid : validate the document in addition to std well-formed check\n");
1313 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
1314 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
Daniel Veillard66f68e72003-08-18 16:39:51 +00001315 printf("\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001316 printf("\t--timing : print some timings\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001317 printf("\t--output file or -o file: save to a given file\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001318 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
1319 printf("\t--insert : ad-hoc test for valid insertions\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001320#ifdef HAVE_ZLIB_H
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001321 printf("\t--compress : turn on gzip compression of output\n");
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001322#endif
Daniel Veillard89cad532001-10-22 09:46:13 +00001323#ifdef LIBXML_DOCB_ENABLED
1324 printf("\t--sgml : use the DocBook SGML parser\n");
1325#endif
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001326#ifdef LIBXML_HTML_ENABLED
1327 printf("\t--html : use the HTML parser\n");
1328#endif
1329 printf("\t--push : use the push mode of the parser\n");
1330#ifdef HAVE_SYS_MMAN_H
1331 printf("\t--memory : parse from memory\n");
1332#endif
1333 printf("\t--nowarning : do not emit warnings from parser/validator\n");
1334 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
Daniel Veillard90493a92001-08-14 14:12:47 +00001335 printf("\t--format : reformat/reindent the input\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001336 printf("\t--testIO : test user I/O support\n");
1337 printf("\t--encode encoding : output in the given encoding\n");
1338#ifdef LIBXML_CATALOG_ENABLED
Daniel Veillardbd9b0e82001-11-26 10:32:08 +00001339 printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
1340 printf("\t otherwise XML Catalogs starting from \n");
Daniel Veillard3be27512003-01-26 19:49:04 +00001341 printf("\t " XML_XML_DEFAULT_CATALOG " are activated by default\n");
Daniel Veillard05c13a22001-09-09 08:38:09 +00001342 printf("\t--nocatalogs: deactivate all catalogs\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001343#endif
1344 printf("\t--auto : generate a small doc on the fly\n");
1345#ifdef LIBXML_XINCLUDE_ENABLED
1346 printf("\t--xinclude : do XInclude processing\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001347#endif
Daniel Veillardcbaf3992001-12-31 16:16:02 +00001348 printf("\t--loaddtd : fetch external DTD\n");
Daniel Veillard48da9102001-08-07 01:10:10 +00001349 printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
Daniel Veillard29e43992001-12-13 22:21:58 +00001350 printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
Daniel Veillard7704fb12003-01-03 16:19:51 +00001351 printf("\t--stream : use the streaming interface to process very large files\n");
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001352 printf("\t--chkregister : verify the node registration code\n");
Daniel Veillardef4d3bc2003-02-07 12:38:22 +00001353#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillard71531f32003-02-05 13:19:53 +00001354 printf("\t--relaxng schema : do RelaxNG validation against the schema\n");
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001355 printf("\t--schema schema : do validation against the WXS schema\n");
Daniel Veillard71531f32003-02-05 13:19:53 +00001356#endif
Daniel Veillarda42f25f2002-01-25 14:15:40 +00001357 printf("\nLibxml project home page: http://xmlsoft.org/\n");
1358 printf("To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001359}
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001360
1361static void registerNode(xmlNodePtr node)
1362{
1363 node->_private = malloc(sizeof(long));
1364 *(long*)node->_private = (long) 0x81726354;
1365}
1366
1367static void deregisterNode(xmlNodePtr node)
1368{
1369 assert(node->_private != NULL);
1370 assert(*(long*)node->_private == (long) 0x81726354);
1371 free(node->_private);
1372}
1373
Daniel Veillard4a6845d2001-01-03 13:32:39 +00001374int
1375main(int argc, char **argv) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00001376 int i, acount;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001377 int files = 0;
Daniel Veillard845cce42002-01-09 11:51:37 +00001378 int version = 0;
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00001379 const char* indent;
1380
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001381 if (argc <= 1) {
1382 usage(argv[0]);
1383 return(1);
1384 }
Daniel Veillardbe803962000-06-28 23:40:59 +00001385 LIBXML_TEST_VERSION
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001386 for (i = 1; i < argc ; i++) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001387 if (!strcmp(argv[i], "-"))
1388 break;
1389
1390 if (argv[i][0] != '-')
1391 continue;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001392 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
1393 debug++;
Daniel Veillard56ada1d2003-01-07 11:17:25 +00001394 else
1395#ifdef LIBXML_DEBUG_ENABLED
1396 if ((!strcmp(argv[i], "-shell")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001397 (!strcmp(argv[i], "--shell"))) {
1398 shell++;
1399 noout = 1;
1400 } else
1401#endif
1402 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
1403 copy++;
1404 else if ((!strcmp(argv[i], "-recover")) ||
1405 (!strcmp(argv[i], "--recover")))
1406 recovery++;
1407 else if ((!strcmp(argv[i], "-noent")) ||
1408 (!strcmp(argv[i], "--noent")))
1409 noent++;
Daniel Veillard4ec885a2001-06-17 10:31:07 +00001410 else if ((!strcmp(argv[i], "-version")) ||
Daniel Veillard845cce42002-01-09 11:51:37 +00001411 (!strcmp(argv[i], "--version"))) {
Daniel Veillard0f04f8e2002-09-17 23:04:40 +00001412 showVersion(argv[0]);
Daniel Veillard845cce42002-01-09 11:51:37 +00001413 version = 1;
1414 } else if ((!strcmp(argv[i], "-noout")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001415 (!strcmp(argv[i], "--noout")))
1416 noout++;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001417 else if ((!strcmp(argv[i], "-o")) ||
1418 (!strcmp(argv[i], "-output")) ||
1419 (!strcmp(argv[i], "--output"))) {
1420 i++;
Daniel Veillard6e4f1c02002-04-09 09:55:20 +00001421 output = argv[i];
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001422 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001423 else if ((!strcmp(argv[i], "-htmlout")) ||
1424 (!strcmp(argv[i], "--htmlout")))
1425 htmlout++;
Daniel Veillard89cad532001-10-22 09:46:13 +00001426#ifdef LIBXML_DOCB_ENABLED
1427 else if ((!strcmp(argv[i], "-sgml")) ||
1428 (!strcmp(argv[i], "--sgml"))) {
1429 sgml++;
1430 }
1431#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001432#ifdef LIBXML_HTML_ENABLED
1433 else if ((!strcmp(argv[i], "-html")) ||
1434 (!strcmp(argv[i], "--html"))) {
1435 html++;
1436 }
1437#endif /* LIBXML_HTML_ENABLED */
1438 else if ((!strcmp(argv[i], "-nowrap")) ||
1439 (!strcmp(argv[i], "--nowrap")))
1440 nowrap++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001441 else if ((!strcmp(argv[i], "-loaddtd")) ||
1442 (!strcmp(argv[i], "--loaddtd")))
1443 loaddtd++;
Daniel Veillard48da9102001-08-07 01:10:10 +00001444 else if ((!strcmp(argv[i], "-dtdattr")) ||
1445 (!strcmp(argv[i], "--dtdattr"))) {
1446 loaddtd++;
1447 dtdattrs++;
1448 } else if ((!strcmp(argv[i], "-valid")) ||
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001449 (!strcmp(argv[i], "--valid")))
1450 valid++;
1451 else if ((!strcmp(argv[i], "-postvalid")) ||
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001452 (!strcmp(argv[i], "--postvalid"))) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001453 postvalid++;
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001454 loaddtd++;
1455 } else if ((!strcmp(argv[i], "-dtdvalid")) ||
Daniel Veillardcd429612000-10-11 15:57:05 +00001456 (!strcmp(argv[i], "--dtdvalid"))) {
1457 i++;
1458 dtdvalid = argv[i];
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001459 loaddtd++;
Daniel Veillard66f68e72003-08-18 16:39:51 +00001460 } else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
1461 (!strcmp(argv[i], "--dtdvalidfpi"))) {
1462 i++;
1463 dtdvalidfpi = argv[i];
1464 loaddtd++;
Daniel Veillardcd429612000-10-11 15:57:05 +00001465 }
Daniel Veillard29e43992001-12-13 22:21:58 +00001466 else if ((!strcmp(argv[i], "-dropdtd")) ||
1467 (!strcmp(argv[i], "--dropdtd")))
1468 dropdtd++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001469 else if ((!strcmp(argv[i], "-insert")) ||
1470 (!strcmp(argv[i], "--insert")))
1471 insert++;
Daniel Veillard48b2f892001-02-25 16:11:03 +00001472 else if ((!strcmp(argv[i], "-timing")) ||
1473 (!strcmp(argv[i], "--timing")))
1474 timing++;
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001475 else if ((!strcmp(argv[i], "-auto")) ||
1476 (!strcmp(argv[i], "--auto")))
1477 generate++;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001478 else if ((!strcmp(argv[i], "-repeat")) ||
1479 (!strcmp(argv[i], "--repeat")))
1480 repeat++;
1481 else if ((!strcmp(argv[i], "-push")) ||
1482 (!strcmp(argv[i], "--push")))
1483 push++;
Daniel Veillard46e370e2000-07-21 20:32:03 +00001484#ifdef HAVE_SYS_MMAN_H
1485 else if ((!strcmp(argv[i], "-memory")) ||
1486 (!strcmp(argv[i], "--memory")))
1487 memory++;
1488#endif
Daniel Veillard5e873c42000-04-12 13:27:38 +00001489 else if ((!strcmp(argv[i], "-testIO")) ||
1490 (!strcmp(argv[i], "--testIO")))
1491 testIO++;
Daniel Veillard9e8bfae2000-11-06 16:43:11 +00001492#ifdef LIBXML_XINCLUDE_ENABLED
1493 else if ((!strcmp(argv[i], "-xinclude")) ||
1494 (!strcmp(argv[i], "--xinclude")))
1495 xinclude++;
1496#endif
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001497#ifdef HAVE_ZLIB_H
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001498 else if ((!strcmp(argv[i], "-compress")) ||
1499 (!strcmp(argv[i], "--compress"))) {
1500 compress++;
1501 xmlSetCompressMode(9);
1502 }
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001503#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001504 else if ((!strcmp(argv[i], "-nowarning")) ||
1505 (!strcmp(argv[i], "--nowarning"))) {
1506 xmlGetWarningsDefaultValue = 0;
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001507 xmlPedanticParserDefault(0);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001508 }
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001509 else if ((!strcmp(argv[i], "-pedantic")) ||
1510 (!strcmp(argv[i], "--pedantic"))) {
1511 xmlGetWarningsDefaultValue = 1;
1512 xmlPedanticParserDefault(1);
1513 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00001514#ifdef LIBXML_DEBUG_ENABLED
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001515 else if ((!strcmp(argv[i], "-debugent")) ||
1516 (!strcmp(argv[i], "--debugent"))) {
1517 debugent++;
1518 xmlParserDebugEntities = 1;
1519 }
Daniel Veillard64c20ed2000-09-22 16:07:02 +00001520#endif
Daniel Veillard81418e32001-05-22 15:08:55 +00001521#ifdef LIBXML_CATALOG_ENABLED
1522 else if ((!strcmp(argv[i], "-catalogs")) ||
1523 (!strcmp(argv[i], "--catalogs"))) {
Daniel Veillarde2940dd2001-08-22 00:06:49 +00001524 catalogs++;
1525 } else if ((!strcmp(argv[i], "-nocatalogs")) ||
1526 (!strcmp(argv[i], "--nocatalogs"))) {
1527 nocatalogs++;
Daniel Veillard81418e32001-05-22 15:08:55 +00001528 }
1529#endif
Daniel Veillardbe803962000-06-28 23:40:59 +00001530 else if ((!strcmp(argv[i], "-encode")) ||
1531 (!strcmp(argv[i], "--encode"))) {
1532 i++;
1533 encoding = argv[i];
Daniel Veillardf0cc7cc2000-08-26 21:40:43 +00001534 /*
1535 * OK it's for testing purposes
1536 */
1537 xmlAddEncodingAlias("UTF-8", "DVEnc");
Daniel Veillardbe803962000-06-28 23:40:59 +00001538 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001539 else if ((!strcmp(argv[i], "-noblanks")) ||
1540 (!strcmp(argv[i], "--noblanks"))) {
1541 noblanks++;
1542 xmlKeepBlanksDefault(0);
Daniel Veillard90493a92001-08-14 14:12:47 +00001543 }
1544 else if ((!strcmp(argv[i], "-format")) ||
1545 (!strcmp(argv[i], "--format"))) {
1546 noblanks++;
1547 format++;
1548 xmlKeepBlanksDefault(0);
Daniel Veillard7704fb12003-01-03 16:19:51 +00001549 }
1550 else if ((!strcmp(argv[i], "-stream")) ||
1551 (!strcmp(argv[i], "--stream"))) {
1552 stream++;
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001553 }
Daniel Veillard07cb8222003-09-10 10:51:05 +00001554 else if ((!strcmp(argv[i], "-sax1")) ||
1555 (!strcmp(argv[i], "--sax1"))) {
1556 sax1++;
1557 }
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001558 else if ((!strcmp(argv[i], "-chkregister")) ||
1559 (!strcmp(argv[i], "--chkregister"))) {
1560 chkregister++;
Daniel Veillard71531f32003-02-05 13:19:53 +00001561#ifdef LIBXML_SCHEMAS_ENABLED
1562 } else if ((!strcmp(argv[i], "-relaxng")) ||
1563 (!strcmp(argv[i], "--relaxng"))) {
1564 i++;
1565 relaxng = argv[i];
1566 noent++;
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001567 } else if ((!strcmp(argv[i], "-schema")) ||
1568 (!strcmp(argv[i], "--schema"))) {
1569 i++;
1570 schema = argv[i];
1571 noent++;
Daniel Veillard71531f32003-02-05 13:19:53 +00001572#endif
Daniel Veillarde8b09e42003-05-13 22:14:13 +00001573 } else if ((!strcmp(argv[i], "-nonet")) ||
1574 (!strcmp(argv[i], "--nonet"))) {
1575 xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001576 } else {
1577 fprintf(stderr, "Unknown option %s\n", argv[i]);
1578 usage(argv[0]);
1579 return(1);
1580 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001581 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00001582
1583#ifdef LIBXML_CATALOG_ENABLED
1584 if (nocatalogs == 0) {
1585 if (catalogs) {
1586 const char *catal;
1587
1588 catal = getenv("SGML_CATALOG_FILES");
Daniel Veillard6c5f9d12001-08-25 13:33:14 +00001589 if (catal != NULL) {
1590 xmlLoadCatalogs(catal);
1591 } else {
1592 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
1593 }
Daniel Veillarde2940dd2001-08-22 00:06:49 +00001594 }
1595 }
1596#endif
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001597
Daniel Veillard07cb8222003-09-10 10:51:05 +00001598 if (sax1)
1599 xmlSAXDefaultVersion(1);
1600 else
1601 xmlSAXDefaultVersion(2);
1602
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001603 if (chkregister) {
1604 xmlRegisterNodeDefault(registerNode);
1605 xmlDeregisterNodeDefault(deregisterNode);
1606 }
Aleksey Sanin693c9bc2003-03-09 22:36:52 +00001607
1608 indent = getenv("XMLLINT_INDENT");
1609 if(indent != NULL) {
1610 xmlTreeIndentString = indent;
1611 }
1612
Daniel Veillard8a1b1852003-01-05 22:37:17 +00001613
Daniel Veillardd9bad132001-07-23 19:39:43 +00001614 xmlLineNumbersDefault(1);
Daniel Veillard48da9102001-08-07 01:10:10 +00001615 if (loaddtd != 0)
1616 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
1617 if (dtdattrs)
1618 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001619 if (noent != 0) xmlSubstituteEntitiesDefault(1);
1620 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
1621 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001622 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001623 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001624 xmlGenericError(xmlGenericErrorContext,
1625 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
1626 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001627 "<html><head><title>%s output</title></head>\n",
1628 argv[0]);
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001629 xmlGenericError(xmlGenericErrorContext,
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001630 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
1631 argv[0]);
1632 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001633
1634#ifdef LIBXML_SCHEMAS_ENABLED
Daniel Veillardce192eb2003-04-16 15:58:05 +00001635 if ((relaxng != NULL) && (stream == 0)) {
Daniel Veillard71531f32003-02-05 13:19:53 +00001636 xmlRelaxNGParserCtxtPtr ctxt;
1637
Daniel Veillardce192eb2003-04-16 15:58:05 +00001638 /* forces loading the DTDs */
1639 xmlLoadExtDtdDefaultValue |= 1;
Daniel Veillard42f12e92003-03-07 18:32:59 +00001640 if (timing) {
1641 startTimer();
1642 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001643 ctxt = xmlRelaxNGNewParserCtxt(relaxng);
1644 xmlRelaxNGSetParserErrors(ctxt,
1645 (xmlRelaxNGValidityErrorFunc) fprintf,
1646 (xmlRelaxNGValidityWarningFunc) fprintf,
1647 stderr);
1648 relaxngschemas = xmlRelaxNGParse(ctxt);
Daniel Veillardce192eb2003-04-16 15:58:05 +00001649 if (relaxngschemas == NULL) {
1650 xmlGenericError(xmlGenericErrorContext,
1651 "Relax-NG schema %s failed to compile\n", relaxng);
1652 relaxng = NULL;
1653 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001654 xmlRelaxNGFreeParserCtxt(ctxt);
Daniel Veillard42f12e92003-03-07 18:32:59 +00001655 if (timing) {
1656 endTimer("Compiling the schemas");
1657 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001658 } else if ((schema != NULL) && (stream == 0)) {
1659 xmlSchemaParserCtxtPtr ctxt;
1660
1661 if (timing) {
1662 startTimer();
1663 }
1664 ctxt = xmlSchemaNewParserCtxt(schema);
1665 xmlSchemaSetParserErrors(ctxt,
1666 (xmlSchemaValidityErrorFunc) fprintf,
1667 (xmlSchemaValidityWarningFunc) fprintf,
1668 stderr);
1669 wxschemas = xmlSchemaParse(ctxt);
1670 if (wxschemas == NULL) {
1671 xmlGenericError(xmlGenericErrorContext,
1672 "WXS schema %s failed to compile\n", schema);
1673 schema = NULL;
1674 }
1675 xmlSchemaFreeParserCtxt(ctxt);
1676 if (timing) {
1677 endTimer("Compiling the schemas");
1678 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001679 }
1680#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001681 for (i = 1; i < argc ; i++) {
Daniel Veillardbe803962000-06-28 23:40:59 +00001682 if ((!strcmp(argv[i], "-encode")) ||
1683 (!strcmp(argv[i], "--encode"))) {
1684 i++;
1685 continue;
Daniel Veillard1df3dfc2001-12-18 11:14:16 +00001686 } else if ((!strcmp(argv[i], "-o")) ||
1687 (!strcmp(argv[i], "-output")) ||
1688 (!strcmp(argv[i], "--output"))) {
1689 i++;
1690 continue;
Daniel Veillardbe803962000-06-28 23:40:59 +00001691 }
Daniel Veillardcd429612000-10-11 15:57:05 +00001692 if ((!strcmp(argv[i], "-dtdvalid")) ||
1693 (!strcmp(argv[i], "--dtdvalid"))) {
1694 i++;
1695 continue;
1696 }
Daniel Veillard66f68e72003-08-18 16:39:51 +00001697 if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
1698 (!strcmp(argv[i], "--dtdvalidfpi"))) {
1699 i++;
1700 continue;
1701 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001702 if ((!strcmp(argv[i], "-relaxng")) ||
1703 (!strcmp(argv[i], "--relaxng"))) {
1704 i++;
1705 continue;
1706 }
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001707 if ((!strcmp(argv[i], "-schema")) ||
1708 (!strcmp(argv[i], "--schema"))) {
1709 i++;
1710 continue;
1711 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001712 if ((timing) && (repeat))
Daniel Veillard01db67c2001-12-18 07:09:59 +00001713 startTimer();
Daniel Veillardcbaf3992001-12-31 16:16:02 +00001714 /* Remember file names. "-" means stdin. <sven@zen.org> */
Daniel Veillard4a6845d2001-01-03 13:32:39 +00001715 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001716 if (repeat) {
Daniel Veillard7704fb12003-01-03 16:19:51 +00001717 for (acount = 0;acount < 100 * repeat;acount++)
1718 if (stream != 0)
1719 streamFile(argv[i]);
1720 else
1721 parseAndPrintFile(argv[i]);
1722 } else {
1723 if (stream != 0)
1724 streamFile(argv[i]);
1725 else
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001726 parseAndPrintFile(argv[i]);
Daniel Veillard7704fb12003-01-03 16:19:51 +00001727 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001728 files ++;
Daniel Veillarda7866932001-12-04 13:14:44 +00001729 if ((timing) && (repeat)) {
Daniel Veillard01db67c2001-12-18 07:09:59 +00001730 endTimer("100 iterations");
Daniel Veillarda7866932001-12-04 13:14:44 +00001731 }
Daniel Veillard48b2f892001-02-25 16:11:03 +00001732 }
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001733 }
Daniel Veillardd2f3ec72001-04-11 07:50:02 +00001734 if (generate)
1735 parseAndPrintFile(NULL);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001736 if ((htmlout) && (!nowrap)) {
Daniel Veillardd6d7f7b2000-10-25 19:56:55 +00001737 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001738 }
Daniel Veillard845cce42002-01-09 11:51:37 +00001739 if ((files == 0) && (!generate) && (version == 0)) {
Daniel Veillard10ea86c2001-06-20 13:55:33 +00001740 usage(argv[0]);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001741 }
Daniel Veillard71531f32003-02-05 13:19:53 +00001742#ifdef LIBXML_SCHEMAS_ENABLED
1743 if (relaxngschemas != NULL)
1744 xmlRelaxNGFree(relaxngschemas);
Daniel Veillard75bb3bb2003-05-12 15:25:56 +00001745 if (wxschemas != NULL)
1746 xmlSchemaFree(wxschemas);
Daniel Veillard71531f32003-02-05 13:19:53 +00001747 xmlRelaxNGCleanupTypes();
1748#endif
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001749 xmlCleanupParser();
1750 xmlMemoryDump();
1751
Daniel Veillardf7cd4812001-02-23 18:44:52 +00001752 return(progresult);
Daniel Veillardce8b83b2000-04-05 18:38:42 +00001753}
Daniel Veillard88a172f2000-08-04 18:23:10 +00001754