blob: 67f7adb23407c76ee1879c67669f456cb95b30b8 [file] [log] [blame]
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001/*
2 * xmllint.c : a small tester program for XML input.
3 *
4 * See Copyright for the status of this software.
5 *
6 * daniel@veillard.com
7 */
8
9#include "libxml.h"
10
11#include <string.h>
12#include <stdarg.h>
13#include <assert.h>
14
15#if defined (_WIN32) && !defined(__CYGWIN__)
16#if defined (_MSC_VER) || defined(__BORLANDC__)
17#include <winsock2.h>
18#pragma comment(lib, "ws2_32.lib")
19#define gettimeofday(p1,p2)
20#endif /* _MSC_VER */
21#endif /* _WIN32 */
22
23#ifdef HAVE_SYS_TIME_H
24#include <sys/time.h>
25#endif
26#ifdef HAVE_TIME_H
27#include <time.h>
28#endif
29
30#ifdef __MINGW32__
31#define _WINSOCKAPI_
32#include <wsockcompat.h>
33#include <winsock2.h>
34#undef XML_SOCKLEN_T
35#define XML_SOCKLEN_T unsigned int
36#endif
37
38#ifdef HAVE_SYS_TIMEB_H
39#include <sys/timeb.h>
40#endif
41
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
54#ifdef HAVE_SYS_MMAN_H
55#include <sys/mman.h>
56/* seems needed for Solaris */
57#ifndef MAP_FAILED
58#define MAP_FAILED ((void *) -1)
59#endif
60#endif
61#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>
79#include <libxml/xmlerror.h>
80#ifdef LIBXML_XINCLUDE_ENABLED
81#include <libxml/xinclude.h>
82#endif
83#ifdef LIBXML_CATALOG_ENABLED
84#include <libxml/catalog.h>
85#endif
86#include <libxml/globals.h>
87#include <libxml/xmlreader.h>
88#ifdef LIBXML_SCHEMATRON_ENABLED
89#include <libxml/schematron.h>
90#endif
91#ifdef LIBXML_SCHEMAS_ENABLED
92#include <libxml/relaxng.h>
93#include <libxml/xmlschemas.h>
94#endif
95#ifdef LIBXML_PATTERN_ENABLED
96#include <libxml/pattern.h>
97#endif
98#ifdef LIBXML_C14N_ENABLED
99#include <libxml/c14n.h>
100#endif
101#ifdef LIBXML_OUTPUT_ENABLED
102#include <libxml/xmlsave.h>
103#endif
104
105#ifndef XML_XML_DEFAULT_CATALOG
106#define XML_XML_DEFAULT_CATALOG "file:///etc/xml/catalog"
107#endif
108
109typedef enum {
110 XMLLINT_RETURN_OK = 0, /* No error */
Selim Gurundf143a52012-03-05 14:35:53 -0800111 XMLLINT_ERR_UNCLASS = 1, /* Unclassified */
112 XMLLINT_ERR_DTD = 2, /* Error in DTD */
113 XMLLINT_ERR_VALID = 3, /* Validation error */
114 XMLLINT_ERR_RDFILE = 4, /* CtxtReadFile error */
115 XMLLINT_ERR_SCHEMACOMP = 5, /* Schema compilation */
116 XMLLINT_ERR_OUT = 6, /* Error writing output */
117 XMLLINT_ERR_SCHEMAPAT = 7, /* Error in schema pattern */
118 XMLLINT_ERR_RDREGIS = 8, /* Error in Reader registration */
119 XMLLINT_ERR_MEM = 9, /* Out of memory error */
120 XMLLINT_ERR_XPATH = 10 /* XPath evaluation error */
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800121} xmllintReturnCode;
122#ifdef LIBXML_DEBUG_ENABLED
123static int shell = 0;
124static int debugent = 0;
125#endif
126static int debug = 0;
127static int maxmem = 0;
128#ifdef LIBXML_TREE_ENABLED
129static int copy = 0;
130#endif /* LIBXML_TREE_ENABLED */
131static int recovery = 0;
132static int noent = 0;
Selim Gurundf143a52012-03-05 14:35:53 -0800133static int noenc = 0;
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800134static int noblanks = 0;
135static int noout = 0;
136static int nowrap = 0;
137#ifdef LIBXML_OUTPUT_ENABLED
138static int format = 0;
139static const char *output = NULL;
140static int compress = 0;
141static int oldout = 0;
142#endif /* LIBXML_OUTPUT_ENABLED */
143#ifdef LIBXML_VALID_ENABLED
144static int valid = 0;
145static int postvalid = 0;
146static char * dtdvalid = NULL;
147static char * dtdvalidfpi = NULL;
148#endif
149#ifdef LIBXML_SCHEMAS_ENABLED
150static char * relaxng = NULL;
151static xmlRelaxNGPtr relaxngschemas = NULL;
152static char * schema = NULL;
153static xmlSchemaPtr wxschemas = NULL;
154#endif
155#ifdef LIBXML_SCHEMATRON_ENABLED
156static char * schematron = NULL;
157static xmlSchematronPtr wxschematron = NULL;
158#endif
159static int repeat = 0;
160static int insert = 0;
161#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
162static int html = 0;
163static int xmlout = 0;
164#endif
165static int htmlout = 0;
Selim Gurundf143a52012-03-05 14:35:53 -0800166#if defined(LIBXML_HTML_ENABLED)
167static int nodefdtd = 0;
168#endif
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800169#ifdef LIBXML_PUSH_ENABLED
170static int push = 0;
Selim Gurun94442ad2013-12-30 18:23:42 -0800171static int pushsize = 4096;
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800172#endif /* LIBXML_PUSH_ENABLED */
Selim Gurun94442ad2013-12-30 18:23:42 -0800173#ifdef HAVE_MMAP
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800174static int memory = 0;
175#endif
176static int testIO = 0;
177static char *encoding = NULL;
178#ifdef LIBXML_XINCLUDE_ENABLED
179static int xinclude = 0;
180#endif
181static int dtdattrs = 0;
182static int loaddtd = 0;
183static xmllintReturnCode progresult = XMLLINT_RETURN_OK;
184static int timing = 0;
185static int generate = 0;
186static int dropdtd = 0;
187#ifdef LIBXML_CATALOG_ENABLED
188static int catalogs = 0;
189static int nocatalogs = 0;
190#endif
191#ifdef LIBXML_C14N_ENABLED
192static int canonical = 0;
Selim Gurundf143a52012-03-05 14:35:53 -0800193static int canonical_11 = 0;
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800194static int exc_canonical = 0;
195#endif
196#ifdef LIBXML_READER_ENABLED
197static int stream = 0;
198static int walker = 0;
199#endif /* LIBXML_READER_ENABLED */
200static int chkregister = 0;
201static int nbregister = 0;
202#ifdef LIBXML_SAX1_ENABLED
203static int sax1 = 0;
204#endif /* LIBXML_SAX1_ENABLED */
205#ifdef LIBXML_PATTERN_ENABLED
206static const char *pattern = NULL;
207static xmlPatternPtr patternc = NULL;
208static xmlStreamCtxtPtr patstream = NULL;
209#endif
Selim Gurundf143a52012-03-05 14:35:53 -0800210#ifdef LIBXML_XPATH_ENABLED
211static const char *xpathquery = NULL;
212#endif
Selim Gurun94442ad2013-12-30 18:23:42 -0800213static int options = XML_PARSE_COMPACT | XML_PARSE_BIG_LINES;
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800214static int sax = 0;
Patrick Scott60a4c352009-07-09 09:30:54 -0400215static int oldxml10 = 0;
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800216
217/************************************************************************
218 * *
219 * Entity loading control and customization. *
220 * *
221 ************************************************************************/
222#define MAX_PATHS 64
223#ifdef _WIN32
224# define PATH_SEPARATOR ';'
225#else
226# define PATH_SEPARATOR ':'
227#endif
228static xmlChar *paths[MAX_PATHS + 1];
229static int nbpaths = 0;
230static int load_trace = 0;
231
232static
233void parsePath(const xmlChar *path) {
234 const xmlChar *cur;
235
236 if (path == NULL)
237 return;
238 while (*path != 0) {
239 if (nbpaths >= MAX_PATHS) {
240 fprintf(stderr, "MAX_PATHS reached: too many paths\n");
241 return;
242 }
243 cur = path;
244 while ((*cur == ' ') || (*cur == PATH_SEPARATOR))
245 cur++;
246 path = cur;
247 while ((*cur != 0) && (*cur != ' ') && (*cur != PATH_SEPARATOR))
248 cur++;
249 if (cur != path) {
250 paths[nbpaths] = xmlStrndup(path, cur - path);
251 if (paths[nbpaths] != NULL)
252 nbpaths++;
253 path = cur;
254 }
255 }
256}
257
258static xmlExternalEntityLoader defaultEntityLoader = NULL;
259
Selim Gurundf143a52012-03-05 14:35:53 -0800260static xmlParserInputPtr
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800261xmllintExternalEntityLoader(const char *URL, const char *ID,
262 xmlParserCtxtPtr ctxt) {
263 xmlParserInputPtr ret;
264 warningSAXFunc warning = NULL;
265 errorSAXFunc err = NULL;
266
267 int i;
268 const char *lastsegment = URL;
269 const char *iter = URL;
270
271 if ((nbpaths > 0) && (iter != NULL)) {
272 while (*iter != 0) {
273 if (*iter == '/')
274 lastsegment = iter + 1;
275 iter++;
276 }
277 }
278
279 if ((ctxt != NULL) && (ctxt->sax != NULL)) {
280 warning = ctxt->sax->warning;
281 err = ctxt->sax->error;
282 ctxt->sax->warning = NULL;
283 ctxt->sax->error = NULL;
284 }
285
286 if (defaultEntityLoader != NULL) {
287 ret = defaultEntityLoader(URL, ID, ctxt);
288 if (ret != NULL) {
289 if (warning != NULL)
290 ctxt->sax->warning = warning;
291 if (err != NULL)
292 ctxt->sax->error = err;
293 if (load_trace) {
294 fprintf \
295 (stderr,
296 "Loaded URL=\"%s\" ID=\"%s\"\n",
297 URL ? URL : "(null)",
298 ID ? ID : "(null)");
299 }
300 return(ret);
301 }
302 }
303 for (i = 0;i < nbpaths;i++) {
304 xmlChar *newURL;
305
306 newURL = xmlStrdup((const xmlChar *) paths[i]);
307 newURL = xmlStrcat(newURL, (const xmlChar *) "/");
308 newURL = xmlStrcat(newURL, (const xmlChar *) lastsegment);
309 if (newURL != NULL) {
310 ret = defaultEntityLoader((const char *)newURL, ID, ctxt);
311 if (ret != NULL) {
312 if (warning != NULL)
313 ctxt->sax->warning = warning;
314 if (err != NULL)
315 ctxt->sax->error = err;
316 if (load_trace) {
317 fprintf \
Selim Gurundf143a52012-03-05 14:35:53 -0800318 (stderr,
319 "Loaded URL=\"%s\" ID=\"%s\"\n",
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800320 newURL,
Selim Gurundf143a52012-03-05 14:35:53 -0800321 ID ? ID : "(null)");
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800322 }
323 xmlFree(newURL);
324 return(ret);
325 }
326 xmlFree(newURL);
327 }
328 }
329 if (err != NULL)
330 ctxt->sax->error = err;
331 if (warning != NULL) {
332 ctxt->sax->warning = warning;
333 if (URL != NULL)
334 warning(ctxt, "failed to load external entity \"%s\"\n", URL);
335 else if (ID != NULL)
336 warning(ctxt, "failed to load external entity \"%s\"\n", ID);
337 }
338 return(NULL);
339}
340/************************************************************************
Selim Gurundf143a52012-03-05 14:35:53 -0800341 * *
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800342 * Memory allocation consumption debugging *
Selim Gurundf143a52012-03-05 14:35:53 -0800343 * *
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800344 ************************************************************************/
345
346static void
347OOM(void)
348{
349 fprintf(stderr, "Ran out of memory needs > %d bytes\n", maxmem);
350 progresult = XMLLINT_ERR_MEM;
351}
352
353static void
354myFreeFunc(void *mem)
355{
356 xmlMemFree(mem);
357}
358static void *
359myMallocFunc(size_t size)
360{
361 void *ret;
362
363 ret = xmlMemMalloc(size);
364 if (ret != NULL) {
365 if (xmlMemUsed() > maxmem) {
366 OOM();
367 xmlMemFree(ret);
368 return (NULL);
369 }
370 }
371 return (ret);
372}
373static void *
374myReallocFunc(void *mem, size_t size)
375{
376 void *ret;
377
378 ret = xmlMemRealloc(mem, size);
379 if (ret != NULL) {
380 if (xmlMemUsed() > maxmem) {
381 OOM();
382 xmlMemFree(ret);
383 return (NULL);
384 }
385 }
386 return (ret);
387}
388static char *
389myStrdupFunc(const char *str)
390{
391 char *ret;
392
393 ret = xmlMemoryStrdup(str);
394 if (ret != NULL) {
395 if (xmlMemUsed() > maxmem) {
396 OOM();
397 xmlFree(ret);
398 return (NULL);
399 }
400 }
401 return (ret);
402}
403/************************************************************************
Selim Gurundf143a52012-03-05 14:35:53 -0800404 * *
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800405 * Internal timing routines to remove the necessity to have *
406 * unix-specific function calls. *
Selim Gurundf143a52012-03-05 14:35:53 -0800407 * *
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800408 ************************************************************************/
409
Selim Gurundf143a52012-03-05 14:35:53 -0800410#ifndef HAVE_GETTIMEOFDAY
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800411#ifdef HAVE_SYS_TIMEB_H
412#ifdef HAVE_SYS_TIME_H
413#ifdef HAVE_FTIME
414
415static int
416my_gettimeofday(struct timeval *tvp, void *tzp)
417{
418 struct timeb timebuffer;
419
420 ftime(&timebuffer);
421 if (tvp) {
422 tvp->tv_sec = timebuffer.time;
423 tvp->tv_usec = timebuffer.millitm * 1000L;
424 }
425 return (0);
426}
427#define HAVE_GETTIMEOFDAY 1
428#define gettimeofday my_gettimeofday
429
430#endif /* HAVE_FTIME */
431#endif /* HAVE_SYS_TIME_H */
432#endif /* HAVE_SYS_TIMEB_H */
433#endif /* !HAVE_GETTIMEOFDAY */
434
435#if defined(HAVE_GETTIMEOFDAY)
436static struct timeval begin, end;
437
438/*
439 * startTimer: call where you want to start timing
440 */
441static void
442startTimer(void)
443{
444 gettimeofday(&begin, NULL);
445}
446
447/*
448 * endTimer: call where you want to stop timing and to print out a
449 * message about the timing performed; format is a printf
450 * type argument
451 */
Xin Lie742c3a2017-03-02 10:59:49 -0800452static void XMLCDECL LIBXML_ATTR_FORMAT(1,2)
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800453endTimer(const char *fmt, ...)
454{
455 long msec;
456 va_list ap;
457
458 gettimeofday(&end, NULL);
459 msec = end.tv_sec - begin.tv_sec;
460 msec *= 1000;
461 msec += (end.tv_usec - begin.tv_usec) / 1000;
462
463#ifndef HAVE_STDARG_H
464#error "endTimer required stdarg functions"
465#endif
466 va_start(ap, fmt);
467 vfprintf(stderr, fmt, ap);
468 va_end(ap);
469
470 fprintf(stderr, " took %ld ms\n", msec);
471}
472#elif defined(HAVE_TIME_H)
473/*
474 * No gettimeofday function, so we have to make do with calling clock.
475 * This is obviously less accurate, but there's little we can do about
476 * that.
477 */
478#ifndef CLOCKS_PER_SEC
479#define CLOCKS_PER_SEC 100
480#endif
481
482static clock_t begin, end;
483static void
484startTimer(void)
485{
486 begin = clock();
487}
Xin Lie742c3a2017-03-02 10:59:49 -0800488static void XMLCDECL LIBXML_ATTR_FORMAT(1,2)
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800489endTimer(const char *fmt, ...)
490{
491 long msec;
492 va_list ap;
493
494 end = clock();
495 msec = ((end - begin) * 1000) / CLOCKS_PER_SEC;
496
497#ifndef HAVE_STDARG_H
498#error "endTimer required stdarg functions"
499#endif
500 va_start(ap, fmt);
501 vfprintf(stderr, fmt, ap);
502 va_end(ap);
503 fprintf(stderr, " took %ld ms\n", msec);
504}
505#else
506
507/*
508 * We don't have a gettimeofday or time.h, so we just don't do timing
509 */
510static void
511startTimer(void)
512{
513 /*
514 * Do nothing
515 */
516}
Xin Lie742c3a2017-03-02 10:59:49 -0800517static void XMLCDECL LIBXML_ATTR_FORMAT(1,2)
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800518endTimer(char *format, ...)
519{
520 /*
521 * We cannot do anything because we don't have a timing function
522 */
523#ifdef HAVE_STDARG_H
Selim Gurun94442ad2013-12-30 18:23:42 -0800524 va_list ap;
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800525 va_start(ap, format);
526 vfprintf(stderr, format, ap);
527 va_end(ap);
Selim Gurun94442ad2013-12-30 18:23:42 -0800528 fprintf(stderr, " was not timed\n");
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800529#else
530 /* We don't have gettimeofday, time or stdarg.h, what crazy world is
531 * this ?!
532 */
533#endif
534}
535#endif
536/************************************************************************
Selim Gurundf143a52012-03-05 14:35:53 -0800537 * *
538 * HTML ouput *
539 * *
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800540 ************************************************************************/
541static char buffer[50000];
542
543static void
544xmlHTMLEncodeSend(void) {
545 char *result;
546
547 result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
548 if (result) {
549 xmlGenericError(xmlGenericErrorContext, "%s", result);
550 xmlFree(result);
551 }
552 buffer[0] = 0;
553}
554
555/**
556 * xmlHTMLPrintFileInfo:
557 * @input: an xmlParserInputPtr input
Selim Gurundf143a52012-03-05 14:35:53 -0800558 *
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800559 * Displays the associated file and line informations for the current input
560 */
561
562static void
563xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
564 int len;
565 xmlGenericError(xmlGenericErrorContext, "<p>");
566
567 len = strlen(buffer);
568 if (input != NULL) {
569 if (input->filename) {
570 snprintf(&buffer[len], sizeof(buffer) - len, "%s:%d: ", input->filename,
571 input->line);
572 } else {
573 snprintf(&buffer[len], sizeof(buffer) - len, "Entity: line %d: ", input->line);
574 }
575 }
576 xmlHTMLEncodeSend();
577}
578
579/**
580 * xmlHTMLPrintFileContext:
581 * @input: an xmlParserInputPtr input
Selim Gurundf143a52012-03-05 14:35:53 -0800582 *
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800583 * Displays current context within the input content for error tracking
584 */
585
586static void
587xmlHTMLPrintFileContext(xmlParserInputPtr input) {
588 const xmlChar *cur, *base;
589 int len;
590 int n;
591
592 if (input == NULL) return;
593 xmlGenericError(xmlGenericErrorContext, "<pre>\n");
594 cur = input->cur;
595 base = input->base;
596 while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
597 cur--;
598 }
599 n = 0;
600 while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
601 cur--;
602 if ((*cur == '\n') || (*cur == '\r')) cur++;
603 base = cur;
604 n = 0;
605 while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
606 len = strlen(buffer);
Selim Gurundf143a52012-03-05 14:35:53 -0800607 snprintf(&buffer[len], sizeof(buffer) - len, "%c",
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800608 (unsigned char) *cur++);
609 n++;
610 }
611 len = strlen(buffer);
612 snprintf(&buffer[len], sizeof(buffer) - len, "\n");
613 cur = input->cur;
614 while ((*cur == '\n') || (*cur == '\r'))
615 cur--;
616 n = 0;
617 while ((cur != base) && (n++ < 80)) {
618 len = strlen(buffer);
619 snprintf(&buffer[len], sizeof(buffer) - len, " ");
620 base++;
621 }
622 len = strlen(buffer);
623 snprintf(&buffer[len], sizeof(buffer) - len, "^\n");
624 xmlHTMLEncodeSend();
625 xmlGenericError(xmlGenericErrorContext, "</pre>");
626}
627
628/**
629 * xmlHTMLError:
630 * @ctx: an XML parser context
631 * @msg: the message to display/transmit
632 * @...: extra parameters for the message display
Selim Gurundf143a52012-03-05 14:35:53 -0800633 *
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800634 * Display and format an error messages, gives file, line, position and
635 * extra parameters.
636 */
Xin Lie742c3a2017-03-02 10:59:49 -0800637static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800638xmlHTMLError(void *ctx, const char *msg, ...)
639{
640 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
641 xmlParserInputPtr input;
642 va_list args;
643 int len;
644
645 buffer[0] = 0;
646 input = ctxt->input;
647 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
648 input = ctxt->inputTab[ctxt->inputNr - 2];
649 }
Selim Gurundf143a52012-03-05 14:35:53 -0800650
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800651 xmlHTMLPrintFileInfo(input);
652
653 xmlGenericError(xmlGenericErrorContext, "<b>error</b>: ");
654 va_start(args, msg);
655 len = strlen(buffer);
656 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
657 va_end(args);
658 xmlHTMLEncodeSend();
659 xmlGenericError(xmlGenericErrorContext, "</p>\n");
660
661 xmlHTMLPrintFileContext(input);
662 xmlHTMLEncodeSend();
663}
664
665/**
666 * xmlHTMLWarning:
667 * @ctx: an XML parser context
668 * @msg: the message to display/transmit
669 * @...: extra parameters for the message display
Selim Gurundf143a52012-03-05 14:35:53 -0800670 *
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800671 * Display and format a warning messages, gives file, line, position and
672 * extra parameters.
673 */
Xin Lie742c3a2017-03-02 10:59:49 -0800674static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800675xmlHTMLWarning(void *ctx, const char *msg, ...)
676{
677 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
678 xmlParserInputPtr input;
679 va_list args;
680 int len;
681
682 buffer[0] = 0;
683 input = ctxt->input;
684 if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
685 input = ctxt->inputTab[ctxt->inputNr - 2];
686 }
Selim Gurundf143a52012-03-05 14:35:53 -0800687
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800688
689 xmlHTMLPrintFileInfo(input);
Selim Gurundf143a52012-03-05 14:35:53 -0800690
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800691 xmlGenericError(xmlGenericErrorContext, "<b>warning</b>: ");
692 va_start(args, msg);
Selim Gurundf143a52012-03-05 14:35:53 -0800693 len = strlen(buffer);
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800694 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
695 va_end(args);
696 xmlHTMLEncodeSend();
697 xmlGenericError(xmlGenericErrorContext, "</p>\n");
698
699 xmlHTMLPrintFileContext(input);
700 xmlHTMLEncodeSend();
701}
702
703/**
704 * xmlHTMLValidityError:
705 * @ctx: an XML parser context
706 * @msg: the message to display/transmit
707 * @...: extra parameters for the message display
Selim Gurundf143a52012-03-05 14:35:53 -0800708 *
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800709 * Display and format an validity error messages, gives file,
710 * line, position and extra parameters.
711 */
Xin Lie742c3a2017-03-02 10:59:49 -0800712static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800713xmlHTMLValidityError(void *ctx, const char *msg, ...)
714{
715 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
716 xmlParserInputPtr input;
717 va_list args;
718 int len;
719
720 buffer[0] = 0;
721 input = ctxt->input;
722 if ((input->filename == NULL) && (ctxt->inputNr > 1))
723 input = ctxt->inputTab[ctxt->inputNr - 2];
Selim Gurundf143a52012-03-05 14:35:53 -0800724
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800725 xmlHTMLPrintFileInfo(input);
726
727 xmlGenericError(xmlGenericErrorContext, "<b>validity error</b>: ");
728 len = strlen(buffer);
729 va_start(args, msg);
730 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
731 va_end(args);
732 xmlHTMLEncodeSend();
733 xmlGenericError(xmlGenericErrorContext, "</p>\n");
734
735 xmlHTMLPrintFileContext(input);
736 xmlHTMLEncodeSend();
737 progresult = XMLLINT_ERR_VALID;
738}
739
740/**
741 * xmlHTMLValidityWarning:
742 * @ctx: an XML parser context
743 * @msg: the message to display/transmit
744 * @...: extra parameters for the message display
Selim Gurundf143a52012-03-05 14:35:53 -0800745 *
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800746 * Display and format a validity warning messages, gives file, line,
747 * position and extra parameters.
748 */
Xin Lie742c3a2017-03-02 10:59:49 -0800749static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800750xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
751{
752 xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
753 xmlParserInputPtr input;
754 va_list args;
755 int len;
756
757 buffer[0] = 0;
758 input = ctxt->input;
759 if ((input->filename == NULL) && (ctxt->inputNr > 1))
760 input = ctxt->inputTab[ctxt->inputNr - 2];
761
762 xmlHTMLPrintFileInfo(input);
Selim Gurundf143a52012-03-05 14:35:53 -0800763
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800764 xmlGenericError(xmlGenericErrorContext, "<b>validity warning</b>: ");
765 va_start(args, msg);
Selim Gurundf143a52012-03-05 14:35:53 -0800766 len = strlen(buffer);
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800767 vsnprintf(&buffer[len], sizeof(buffer) - len, msg, args);
768 va_end(args);
769 xmlHTMLEncodeSend();
770 xmlGenericError(xmlGenericErrorContext, "</p>\n");
771
772 xmlHTMLPrintFileContext(input);
773 xmlHTMLEncodeSend();
774}
775
776/************************************************************************
Selim Gurundf143a52012-03-05 14:35:53 -0800777 * *
778 * Shell Interface *
779 * *
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800780 ************************************************************************/
781#ifdef LIBXML_DEBUG_ENABLED
782#ifdef LIBXML_XPATH_ENABLED
783/**
784 * xmlShellReadline:
785 * @prompt: the prompt value
786 *
787 * Read a string
Selim Gurundf143a52012-03-05 14:35:53 -0800788 *
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800789 * Returns a pointer to it or NULL on EOF the caller is expected to
790 * free the returned string.
791 */
792static char *
793xmlShellReadline(char *prompt) {
794#ifdef HAVE_LIBREADLINE
795 char *line_read;
796
797 /* Get a line from the user. */
798 line_read = readline (prompt);
799
800 /* If the line has any text in it, save it on the history. */
801 if (line_read && *line_read)
802 add_history (line_read);
803
804 return (line_read);
805#else
806 char line_read[501];
807 char *ret;
808 int len;
809
810 if (prompt != NULL)
811 fprintf(stdout, "%s", prompt);
Xin Lie742c3a2017-03-02 10:59:49 -0800812 fflush(stdout);
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800813 if (!fgets(line_read, 500, stdin))
814 return(NULL);
815 line_read[500] = 0;
816 len = strlen(line_read);
817 ret = (char *) malloc(len + 1);
818 if (ret != NULL) {
819 memcpy (ret, line_read, len + 1);
820 }
821 return(ret);
822#endif
823}
824#endif /* LIBXML_XPATH_ENABLED */
825#endif /* LIBXML_DEBUG_ENABLED */
826
827/************************************************************************
Selim Gurundf143a52012-03-05 14:35:53 -0800828 * *
829 * I/O Interfaces *
830 * *
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800831 ************************************************************************/
832
833static int myRead(FILE *f, char * buf, int len) {
834 return(fread(buf, 1, len, f));
835}
836static void myClose(FILE *f) {
837 if (f != stdin) {
838 fclose(f);
839 }
840}
841
842/************************************************************************
843 * *
Selim Gurundf143a52012-03-05 14:35:53 -0800844 * SAX based tests *
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -0800845 * *
846 ************************************************************************/
847
848/*
849 * empty SAX block
850 */
851static xmlSAXHandler emptySAXHandlerStruct = {
852 NULL, /* internalSubset */
853 NULL, /* isStandalone */
854 NULL, /* hasInternalSubset */
855 NULL, /* hasExternalSubset */
856 NULL, /* resolveEntity */
857 NULL, /* getEntity */
858 NULL, /* entityDecl */
859 NULL, /* notationDecl */
860 NULL, /* attributeDecl */
861 NULL, /* elementDecl */
862 NULL, /* unparsedEntityDecl */
863 NULL, /* setDocumentLocator */
864 NULL, /* startDocument */
865 NULL, /* endDocument */
866 NULL, /* startElement */
867 NULL, /* endElement */
868 NULL, /* reference */
869 NULL, /* characters */
870 NULL, /* ignorableWhitespace */
871 NULL, /* processingInstruction */
872 NULL, /* comment */
873 NULL, /* xmlParserWarning */
874 NULL, /* xmlParserError */
875 NULL, /* xmlParserError */
876 NULL, /* getParameterEntity */
877 NULL, /* cdataBlock; */
878 NULL, /* externalSubset; */
879 XML_SAX2_MAGIC,
880 NULL,
881 NULL, /* startElementNs */
882 NULL, /* endElementNs */
883 NULL /* xmlStructuredErrorFunc */
884};
885
886static xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
887extern xmlSAXHandlerPtr debugSAXHandler;
888static int callbacks;
889
890/**
891 * isStandaloneDebug:
892 * @ctxt: An XML parser context
893 *
894 * Is this document tagged standalone ?
895 *
896 * Returns 1 if true
897 */
898static int
899isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
900{
901 callbacks++;
902 if (noout)
903 return(0);
904 fprintf(stdout, "SAX.isStandalone()\n");
905 return(0);
906}
907
908/**
909 * hasInternalSubsetDebug:
910 * @ctxt: An XML parser context
911 *
912 * Does this document has an internal subset
913 *
914 * Returns 1 if true
915 */
916static int
917hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
918{
919 callbacks++;
920 if (noout)
921 return(0);
922 fprintf(stdout, "SAX.hasInternalSubset()\n");
923 return(0);
924}
925
926/**
927 * hasExternalSubsetDebug:
928 * @ctxt: An XML parser context
929 *
930 * Does this document has an external subset
931 *
932 * Returns 1 if true
933 */
934static int
935hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
936{
937 callbacks++;
938 if (noout)
939 return(0);
940 fprintf(stdout, "SAX.hasExternalSubset()\n");
941 return(0);
942}
943
944/**
945 * internalSubsetDebug:
946 * @ctxt: An XML parser context
947 *
948 * Does this document has an internal subset
949 */
950static void
951internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
952 const xmlChar *ExternalID, const xmlChar *SystemID)
953{
954 callbacks++;
955 if (noout)
956 return;
957 fprintf(stdout, "SAX.internalSubset(%s,", name);
958 if (ExternalID == NULL)
959 fprintf(stdout, " ,");
960 else
961 fprintf(stdout, " %s,", ExternalID);
962 if (SystemID == NULL)
963 fprintf(stdout, " )\n");
964 else
965 fprintf(stdout, " %s)\n", SystemID);
966}
967
968/**
969 * externalSubsetDebug:
970 * @ctxt: An XML parser context
971 *
972 * Does this document has an external subset
973 */
974static void
975externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
976 const xmlChar *ExternalID, const xmlChar *SystemID)
977{
978 callbacks++;
979 if (noout)
980 return;
981 fprintf(stdout, "SAX.externalSubset(%s,", name);
982 if (ExternalID == NULL)
983 fprintf(stdout, " ,");
984 else
985 fprintf(stdout, " %s,", ExternalID);
986 if (SystemID == NULL)
987 fprintf(stdout, " )\n");
988 else
989 fprintf(stdout, " %s)\n", SystemID);
990}
991
992/**
993 * resolveEntityDebug:
994 * @ctxt: An XML parser context
995 * @publicId: The public ID of the entity
996 * @systemId: The system ID of the entity
997 *
998 * Special entity resolver, better left to the parser, it has
999 * more context than the application layer.
1000 * The default behaviour is to NOT resolve the entities, in that case
1001 * the ENTITY_REF nodes are built in the structure (and the parameter
1002 * values).
1003 *
1004 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
1005 */
1006static xmlParserInputPtr
1007resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
1008{
1009 callbacks++;
1010 if (noout)
1011 return(NULL);
1012 /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
1013
Selim Gurundf143a52012-03-05 14:35:53 -08001014
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001015 fprintf(stdout, "SAX.resolveEntity(");
1016 if (publicId != NULL)
1017 fprintf(stdout, "%s", (char *)publicId);
1018 else
1019 fprintf(stdout, " ");
1020 if (systemId != NULL)
1021 fprintf(stdout, ", %s)\n", (char *)systemId);
1022 else
1023 fprintf(stdout, ", )\n");
1024 return(NULL);
1025}
1026
1027/**
1028 * getEntityDebug:
1029 * @ctxt: An XML parser context
1030 * @name: The entity name
1031 *
1032 * Get an entity by name
1033 *
1034 * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
1035 */
1036static xmlEntityPtr
1037getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1038{
1039 callbacks++;
1040 if (noout)
1041 return(NULL);
1042 fprintf(stdout, "SAX.getEntity(%s)\n", name);
1043 return(NULL);
1044}
1045
1046/**
1047 * getParameterEntityDebug:
1048 * @ctxt: An XML parser context
1049 * @name: The entity name
1050 *
1051 * Get a parameter entity by name
1052 *
1053 * Returns the xmlParserInputPtr
1054 */
1055static xmlEntityPtr
1056getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1057{
1058 callbacks++;
1059 if (noout)
1060 return(NULL);
1061 fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
1062 return(NULL);
1063}
1064
1065
1066/**
1067 * entityDeclDebug:
1068 * @ctxt: An XML parser context
Selim Gurundf143a52012-03-05 14:35:53 -08001069 * @name: the entity name
1070 * @type: the entity type
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001071 * @publicId: The public ID of the entity
1072 * @systemId: The system ID of the entity
1073 * @content: the entity value (without processing).
1074 *
1075 * An entity definition has been parsed
1076 */
1077static void
1078entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
1079 const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
1080{
1081const xmlChar *nullstr = BAD_CAST "(null)";
1082 /* not all libraries handle printing null pointers nicely */
1083 if (publicId == NULL)
1084 publicId = nullstr;
1085 if (systemId == NULL)
1086 systemId = nullstr;
1087 if (content == NULL)
1088 content = (xmlChar *)nullstr;
1089 callbacks++;
1090 if (noout)
1091 return;
1092 fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
1093 name, type, publicId, systemId, content);
1094}
1095
1096/**
1097 * attributeDeclDebug:
1098 * @ctxt: An XML parser context
Selim Gurundf143a52012-03-05 14:35:53 -08001099 * @name: the attribute name
1100 * @type: the attribute type
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001101 *
1102 * An attribute definition has been parsed
1103 */
1104static void
1105attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar * elem,
1106 const xmlChar * name, int type, int def,
1107 const xmlChar * defaultValue, xmlEnumerationPtr tree)
1108{
1109 callbacks++;
1110 if (noout)
1111 return;
1112 if (defaultValue == NULL)
1113 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
1114 elem, name, type, def);
1115 else
1116 fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, %s, ...)\n",
1117 elem, name, type, def, defaultValue);
1118 xmlFreeEnumeration(tree);
1119}
1120
1121/**
1122 * elementDeclDebug:
1123 * @ctxt: An XML parser context
Selim Gurundf143a52012-03-05 14:35:53 -08001124 * @name: the element name
1125 * @type: the element type
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001126 * @content: the element value (without processing).
1127 *
1128 * An element definition has been parsed
1129 */
1130static void
1131elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
1132 xmlElementContentPtr content ATTRIBUTE_UNUSED)
1133{
1134 callbacks++;
1135 if (noout)
1136 return;
1137 fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
1138 name, type);
1139}
1140
1141/**
1142 * notationDeclDebug:
1143 * @ctxt: An XML parser context
1144 * @name: The name of the notation
1145 * @publicId: The public ID of the entity
1146 * @systemId: The system ID of the entity
1147 *
1148 * What to do when a notation declaration has been parsed.
1149 */
1150static void
1151notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
1152 const xmlChar *publicId, const xmlChar *systemId)
1153{
1154 callbacks++;
1155 if (noout)
1156 return;
1157 fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
1158 (char *) name, (char *) publicId, (char *) systemId);
1159}
1160
1161/**
1162 * unparsedEntityDeclDebug:
1163 * @ctxt: An XML parser context
1164 * @name: The name of the entity
1165 * @publicId: The public ID of the entity
1166 * @systemId: The system ID of the entity
1167 * @notationName: the name of the notation
1168 *
1169 * What to do when an unparsed entity declaration is parsed
1170 */
1171static void
1172unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
1173 const xmlChar *publicId, const xmlChar *systemId,
1174 const xmlChar *notationName)
1175{
1176const xmlChar *nullstr = BAD_CAST "(null)";
1177
1178 if (publicId == NULL)
1179 publicId = nullstr;
1180 if (systemId == NULL)
1181 systemId = nullstr;
1182 if (notationName == NULL)
1183 notationName = nullstr;
1184 callbacks++;
1185 if (noout)
1186 return;
1187 fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
1188 (char *) name, (char *) publicId, (char *) systemId,
1189 (char *) notationName);
1190}
1191
1192/**
1193 * setDocumentLocatorDebug:
1194 * @ctxt: An XML parser context
1195 * @loc: A SAX Locator
1196 *
1197 * Receive the document locator at startup, actually xmlDefaultSAXLocator
1198 * Everything is available on the context, so this is useless in our case.
1199 */
1200static void
1201setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
1202{
1203 callbacks++;
1204 if (noout)
1205 return;
1206 fprintf(stdout, "SAX.setDocumentLocator()\n");
1207}
1208
1209/**
1210 * startDocumentDebug:
1211 * @ctxt: An XML parser context
1212 *
1213 * called when the document start being processed.
1214 */
1215static void
1216startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
1217{
1218 callbacks++;
1219 if (noout)
1220 return;
1221 fprintf(stdout, "SAX.startDocument()\n");
1222}
1223
1224/**
1225 * endDocumentDebug:
1226 * @ctxt: An XML parser context
1227 *
1228 * called when the document end has been detected.
1229 */
1230static void
1231endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
1232{
1233 callbacks++;
1234 if (noout)
1235 return;
1236 fprintf(stdout, "SAX.endDocument()\n");
1237}
1238
1239/**
1240 * startElementDebug:
1241 * @ctxt: An XML parser context
1242 * @name: The element name
1243 *
1244 * called when an opening tag has been processed.
1245 */
1246static void
1247startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
1248{
1249 int i;
1250
1251 callbacks++;
1252 if (noout)
1253 return;
1254 fprintf(stdout, "SAX.startElement(%s", (char *) name);
1255 if (atts != NULL) {
1256 for (i = 0;(atts[i] != NULL);i++) {
1257 fprintf(stdout, ", %s='", atts[i++]);
1258 if (atts[i] != NULL)
1259 fprintf(stdout, "%s'", atts[i]);
1260 }
1261 }
1262 fprintf(stdout, ")\n");
1263}
1264
1265/**
1266 * endElementDebug:
1267 * @ctxt: An XML parser context
1268 * @name: The element name
1269 *
1270 * called when the end of an element has been detected.
1271 */
1272static void
1273endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1274{
1275 callbacks++;
1276 if (noout)
1277 return;
1278 fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
1279}
1280
1281/**
1282 * charactersDebug:
1283 * @ctxt: An XML parser context
1284 * @ch: a xmlChar string
1285 * @len: the number of xmlChar
1286 *
1287 * receiving some chars from the parser.
1288 * Question: how much at a time ???
1289 */
1290static void
1291charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
1292{
1293 char out[40];
1294 int i;
1295
1296 callbacks++;
1297 if (noout)
1298 return;
1299 for (i = 0;(i<len) && (i < 30);i++)
1300 out[i] = ch[i];
1301 out[i] = 0;
1302
1303 fprintf(stdout, "SAX.characters(%s, %d)\n", out, len);
1304}
1305
1306/**
1307 * referenceDebug:
1308 * @ctxt: An XML parser context
1309 * @name: The entity name
1310 *
Selim Gurundf143a52012-03-05 14:35:53 -08001311 * called when an entity reference is detected.
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001312 */
1313static void
1314referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
1315{
1316 callbacks++;
1317 if (noout)
1318 return;
1319 fprintf(stdout, "SAX.reference(%s)\n", name);
1320}
1321
1322/**
1323 * ignorableWhitespaceDebug:
1324 * @ctxt: An XML parser context
1325 * @ch: a xmlChar string
1326 * @start: the first char in the string
1327 * @len: the number of xmlChar
1328 *
1329 * receiving some ignorable whitespaces from the parser.
1330 * Question: how much at a time ???
1331 */
1332static void
1333ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
1334{
1335 char out[40];
1336 int i;
1337
1338 callbacks++;
1339 if (noout)
1340 return;
1341 for (i = 0;(i<len) && (i < 30);i++)
1342 out[i] = ch[i];
1343 out[i] = 0;
1344 fprintf(stdout, "SAX.ignorableWhitespace(%s, %d)\n", out, len);
1345}
1346
1347/**
1348 * processingInstructionDebug:
1349 * @ctxt: An XML parser context
1350 * @target: the target name
1351 * @data: the PI data's
1352 * @len: the number of xmlChar
1353 *
1354 * A processing instruction has been parsed.
1355 */
1356static void
1357processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
1358 const xmlChar *data)
1359{
1360 callbacks++;
1361 if (noout)
1362 return;
1363 if (data != NULL)
1364 fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
1365 (char *) target, (char *) data);
1366 else
1367 fprintf(stdout, "SAX.processingInstruction(%s, NULL)\n",
1368 (char *) target);
1369}
1370
1371/**
1372 * cdataBlockDebug:
1373 * @ctx: the user data (XML parser context)
1374 * @value: The pcdata content
1375 * @len: the block length
1376 *
1377 * called when a pcdata block has been parsed
1378 */
1379static void
1380cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
1381{
1382 callbacks++;
1383 if (noout)
1384 return;
1385 fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
1386 (char *) value, len);
1387}
1388
1389/**
1390 * commentDebug:
1391 * @ctxt: An XML parser context
1392 * @value: the comment content
1393 *
1394 * A comment has been parsed.
1395 */
1396static void
1397commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
1398{
1399 callbacks++;
1400 if (noout)
1401 return;
1402 fprintf(stdout, "SAX.comment(%s)\n", value);
1403}
1404
1405/**
1406 * warningDebug:
1407 * @ctxt: An XML parser context
1408 * @msg: the message to display/transmit
1409 * @...: extra parameters for the message display
1410 *
1411 * Display and format a warning messages, gives file, line, position and
1412 * extra parameters.
1413 */
Xin Lie742c3a2017-03-02 10:59:49 -08001414static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001415warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1416{
1417 va_list args;
1418
1419 callbacks++;
1420 if (noout)
1421 return;
1422 va_start(args, msg);
1423 fprintf(stdout, "SAX.warning: ");
1424 vfprintf(stdout, msg, args);
1425 va_end(args);
1426}
1427
1428/**
1429 * errorDebug:
1430 * @ctxt: An XML parser context
1431 * @msg: the message to display/transmit
1432 * @...: extra parameters for the message display
1433 *
1434 * Display and format a error messages, gives file, line, position and
1435 * extra parameters.
1436 */
Xin Lie742c3a2017-03-02 10:59:49 -08001437static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001438errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1439{
1440 va_list args;
1441
1442 callbacks++;
1443 if (noout)
1444 return;
1445 va_start(args, msg);
1446 fprintf(stdout, "SAX.error: ");
1447 vfprintf(stdout, msg, args);
1448 va_end(args);
1449}
1450
1451/**
1452 * fatalErrorDebug:
1453 * @ctxt: An XML parser context
1454 * @msg: the message to display/transmit
1455 * @...: extra parameters for the message display
1456 *
1457 * Display and format a fatalError messages, gives file, line, position and
1458 * extra parameters.
1459 */
Xin Lie742c3a2017-03-02 10:59:49 -08001460static void XMLCDECL LIBXML_ATTR_FORMAT(2,3)
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001461fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
1462{
1463 va_list args;
1464
1465 callbacks++;
1466 if (noout)
1467 return;
1468 va_start(args, msg);
1469 fprintf(stdout, "SAX.fatalError: ");
1470 vfprintf(stdout, msg, args);
1471 va_end(args);
1472}
1473
1474static xmlSAXHandler debugSAXHandlerStruct = {
1475 internalSubsetDebug,
1476 isStandaloneDebug,
1477 hasInternalSubsetDebug,
1478 hasExternalSubsetDebug,
1479 resolveEntityDebug,
1480 getEntityDebug,
1481 entityDeclDebug,
1482 notationDeclDebug,
1483 attributeDeclDebug,
1484 elementDeclDebug,
1485 unparsedEntityDeclDebug,
1486 setDocumentLocatorDebug,
1487 startDocumentDebug,
1488 endDocumentDebug,
1489 startElementDebug,
1490 endElementDebug,
1491 referenceDebug,
1492 charactersDebug,
1493 ignorableWhitespaceDebug,
1494 processingInstructionDebug,
1495 commentDebug,
1496 warningDebug,
1497 errorDebug,
1498 fatalErrorDebug,
1499 getParameterEntityDebug,
1500 cdataBlockDebug,
1501 externalSubsetDebug,
1502 1,
1503 NULL,
1504 NULL,
1505 NULL,
1506 NULL
1507};
1508
1509xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
1510
1511/*
1512 * SAX2 specific callbacks
1513 */
1514/**
1515 * startElementNsDebug:
1516 * @ctxt: An XML parser context
1517 * @name: The element name
1518 *
1519 * called when an opening tag has been processed.
1520 */
1521static void
1522startElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
1523 const xmlChar *localname,
1524 const xmlChar *prefix,
1525 const xmlChar *URI,
1526 int nb_namespaces,
1527 const xmlChar **namespaces,
1528 int nb_attributes,
1529 int nb_defaulted,
1530 const xmlChar **attributes)
1531{
1532 int i;
1533
1534 callbacks++;
1535 if (noout)
1536 return;
1537 fprintf(stdout, "SAX.startElementNs(%s", (char *) localname);
1538 if (prefix == NULL)
1539 fprintf(stdout, ", NULL");
1540 else
1541 fprintf(stdout, ", %s", (char *) prefix);
1542 if (URI == NULL)
1543 fprintf(stdout, ", NULL");
1544 else
1545 fprintf(stdout, ", '%s'", (char *) URI);
1546 fprintf(stdout, ", %d", nb_namespaces);
Selim Gurundf143a52012-03-05 14:35:53 -08001547
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001548 if (namespaces != NULL) {
1549 for (i = 0;i < nb_namespaces * 2;i++) {
1550 fprintf(stdout, ", xmlns");
1551 if (namespaces[i] != NULL)
1552 fprintf(stdout, ":%s", namespaces[i]);
1553 i++;
1554 fprintf(stdout, "='%s'", namespaces[i]);
1555 }
1556 }
1557 fprintf(stdout, ", %d, %d", nb_attributes, nb_defaulted);
1558 if (attributes != NULL) {
1559 for (i = 0;i < nb_attributes * 5;i += 5) {
1560 if (attributes[i + 1] != NULL)
1561 fprintf(stdout, ", %s:%s='", attributes[i + 1], attributes[i]);
1562 else
1563 fprintf(stdout, ", %s='", attributes[i]);
1564 fprintf(stdout, "%.4s...', %d", attributes[i + 3],
1565 (int)(attributes[i + 4] - attributes[i + 3]));
1566 }
1567 }
1568 fprintf(stdout, ")\n");
1569}
1570
1571/**
1572 * endElementDebug:
1573 * @ctxt: An XML parser context
1574 * @name: The element name
1575 *
1576 * called when the end of an element has been detected.
1577 */
1578static void
1579endElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
1580 const xmlChar *localname,
1581 const xmlChar *prefix,
1582 const xmlChar *URI)
1583{
1584 callbacks++;
1585 if (noout)
1586 return;
1587 fprintf(stdout, "SAX.endElementNs(%s", (char *) localname);
1588 if (prefix == NULL)
1589 fprintf(stdout, ", NULL");
1590 else
1591 fprintf(stdout, ", %s", (char *) prefix);
1592 if (URI == NULL)
1593 fprintf(stdout, ", NULL)\n");
1594 else
1595 fprintf(stdout, ", '%s')\n", (char *) URI);
1596}
1597
1598static xmlSAXHandler debugSAX2HandlerStruct = {
1599 internalSubsetDebug,
1600 isStandaloneDebug,
1601 hasInternalSubsetDebug,
1602 hasExternalSubsetDebug,
1603 resolveEntityDebug,
1604 getEntityDebug,
1605 entityDeclDebug,
1606 notationDeclDebug,
1607 attributeDeclDebug,
1608 elementDeclDebug,
1609 unparsedEntityDeclDebug,
1610 setDocumentLocatorDebug,
1611 startDocumentDebug,
1612 endDocumentDebug,
1613 NULL,
1614 NULL,
1615 referenceDebug,
1616 charactersDebug,
1617 ignorableWhitespaceDebug,
1618 processingInstructionDebug,
1619 commentDebug,
1620 warningDebug,
1621 errorDebug,
1622 fatalErrorDebug,
1623 getParameterEntityDebug,
1624 cdataBlockDebug,
1625 externalSubsetDebug,
1626 XML_SAX2_MAGIC,
1627 NULL,
1628 startElementNsDebug,
1629 endElementNsDebug,
1630 NULL
1631};
1632
1633static xmlSAXHandlerPtr debugSAX2Handler = &debugSAX2HandlerStruct;
1634
1635static void
1636testSAX(const char *filename) {
1637 xmlSAXHandlerPtr handler;
1638 const char *user_data = "user_data"; /* mostly for debugging */
1639 xmlParserInputBufferPtr buf = NULL;
1640 xmlParserInputPtr inputStream;
1641 xmlParserCtxtPtr ctxt = NULL;
1642 xmlSAXHandlerPtr old_sax = NULL;
1643
1644 callbacks = 0;
1645
1646 if (noout) {
1647 handler = emptySAXHandler;
1648#ifdef LIBXML_SAX1_ENABLED
1649 } else if (sax1) {
1650 handler = debugSAXHandler;
1651#endif
1652 } else {
1653 handler = debugSAX2Handler;
1654 }
1655
1656 /*
1657 * it's not the simplest code but the most generic in term of I/O
1658 */
1659 buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
1660 if (buf == NULL) {
1661 goto error;
1662 }
1663
1664#ifdef LIBXML_SCHEMAS_ENABLED
1665 if (wxschemas != NULL) {
1666 int ret;
1667 xmlSchemaValidCtxtPtr vctxt;
1668
1669 vctxt = xmlSchemaNewValidCtxt(wxschemas);
1670 xmlSchemaSetValidErrors(vctxt,
1671 (xmlSchemaValidityErrorFunc) fprintf,
1672 (xmlSchemaValidityWarningFunc) fprintf,
1673 stderr);
Selim Gurun94442ad2013-12-30 18:23:42 -08001674 xmlSchemaValidateSetFilename(vctxt, filename);
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001675
1676 ret = xmlSchemaValidateStream(vctxt, buf, 0, handler,
1677 (void *)user_data);
1678 if (repeat == 0) {
1679 if (ret == 0) {
1680 fprintf(stderr, "%s validates\n", filename);
1681 } else if (ret > 0) {
1682 fprintf(stderr, "%s fails to validate\n", filename);
1683 progresult = XMLLINT_ERR_VALID;
1684 } else {
1685 fprintf(stderr, "%s validation generated an internal error\n",
1686 filename);
1687 progresult = XMLLINT_ERR_VALID;
1688 }
1689 }
1690 xmlSchemaFreeValidCtxt(vctxt);
1691 } else
1692#endif
1693 {
1694 /*
1695 * Create the parser context amd hook the input
1696 */
1697 ctxt = xmlNewParserCtxt();
1698 if (ctxt == NULL) {
1699 xmlFreeParserInputBuffer(buf);
1700 goto error;
1701 }
1702 old_sax = ctxt->sax;
1703 ctxt->sax = handler;
1704 ctxt->userData = (void *) user_data;
1705 inputStream = xmlNewIOInputStream(ctxt, buf, XML_CHAR_ENCODING_NONE);
1706 if (inputStream == NULL) {
1707 xmlFreeParserInputBuffer(buf);
1708 goto error;
1709 }
1710 inputPush(ctxt, inputStream);
Selim Gurundf143a52012-03-05 14:35:53 -08001711
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001712 /* do the parsing */
1713 xmlParseDocument(ctxt);
1714
1715 if (ctxt->myDoc != NULL) {
1716 fprintf(stderr, "SAX generated a doc !\n");
1717 xmlFreeDoc(ctxt->myDoc);
1718 ctxt->myDoc = NULL;
1719 }
1720 }
1721
1722error:
1723 if (ctxt != NULL) {
1724 ctxt->sax = old_sax;
1725 xmlFreeParserCtxt(ctxt);
1726 }
1727}
1728
1729/************************************************************************
Selim Gurundf143a52012-03-05 14:35:53 -08001730 * *
1731 * Stream Test processing *
1732 * *
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001733 ************************************************************************/
1734#ifdef LIBXML_READER_ENABLED
1735static void processNode(xmlTextReaderPtr reader) {
1736 const xmlChar *name, *value;
1737 int type, empty;
1738
1739 type = xmlTextReaderNodeType(reader);
1740 empty = xmlTextReaderIsEmptyElement(reader);
1741
1742 if (debug) {
1743 name = xmlTextReaderConstName(reader);
1744 if (name == NULL)
1745 name = BAD_CAST "--";
1746
1747 value = xmlTextReaderConstValue(reader);
1748
Selim Gurundf143a52012-03-05 14:35:53 -08001749
1750 printf("%d %d %s %d %d",
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001751 xmlTextReaderDepth(reader),
1752 type,
1753 name,
1754 empty,
1755 xmlTextReaderHasValue(reader));
1756 if (value == NULL)
1757 printf("\n");
1758 else {
1759 printf(" %s\n", value);
1760 }
1761 }
1762#ifdef LIBXML_PATTERN_ENABLED
1763 if (patternc) {
1764 xmlChar *path = NULL;
1765 int match = -1;
Selim Gurundf143a52012-03-05 14:35:53 -08001766
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001767 if (type == XML_READER_TYPE_ELEMENT) {
1768 /* do the check only on element start */
1769 match = xmlPatternMatch(patternc, xmlTextReaderCurrentNode(reader));
1770
1771 if (match) {
Selim Gurundf143a52012-03-05 14:35:53 -08001772#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001773 path = xmlGetNodePath(xmlTextReaderCurrentNode(reader));
1774 printf("Node %s matches pattern %s\n", path, pattern);
Selim Gurundf143a52012-03-05 14:35:53 -08001775#else
1776 printf("Node %s matches pattern %s\n",
1777 xmlTextReaderConstName(reader), pattern);
1778#endif
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001779 }
1780 }
1781 if (patstream != NULL) {
1782 int ret;
1783
1784 if (type == XML_READER_TYPE_ELEMENT) {
1785 ret = xmlStreamPush(patstream,
1786 xmlTextReaderConstLocalName(reader),
1787 xmlTextReaderConstNamespaceUri(reader));
1788 if (ret < 0) {
1789 fprintf(stderr, "xmlStreamPush() failure\n");
1790 xmlFreeStreamCtxt(patstream);
1791 patstream = NULL;
1792 } else if (ret != match) {
Selim Gurundf143a52012-03-05 14:35:53 -08001793#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001794 if (path == NULL) {
1795 path = xmlGetNodePath(
1796 xmlTextReaderCurrentNode(reader));
1797 }
Selim Gurundf143a52012-03-05 14:35:53 -08001798#endif
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001799 fprintf(stderr,
1800 "xmlPatternMatch and xmlStreamPush disagree\n");
Selim Gurundf143a52012-03-05 14:35:53 -08001801 if (path != NULL)
1802 fprintf(stderr, " pattern %s node %s\n",
1803 pattern, path);
1804 else
1805 fprintf(stderr, " pattern %s node %s\n",
1806 pattern, xmlTextReaderConstName(reader));
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001807 }
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001808
Selim Gurundf143a52012-03-05 14:35:53 -08001809 }
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001810 if ((type == XML_READER_TYPE_END_ELEMENT) ||
1811 ((type == XML_READER_TYPE_ELEMENT) && (empty))) {
1812 ret = xmlStreamPop(patstream);
1813 if (ret < 0) {
1814 fprintf(stderr, "xmlStreamPop() failure\n");
1815 xmlFreeStreamCtxt(patstream);
1816 patstream = NULL;
1817 }
1818 }
1819 }
1820 if (path != NULL)
1821 xmlFree(path);
1822 }
1823#endif
1824}
1825
1826static void streamFile(char *filename) {
1827 xmlTextReaderPtr reader;
1828 int ret;
Selim Gurun94442ad2013-12-30 18:23:42 -08001829#ifdef HAVE_MMAP
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001830 int fd = -1;
1831 struct stat info;
1832 const char *base = NULL;
1833 xmlParserInputBufferPtr input = NULL;
1834
1835 if (memory) {
Selim Gurundf143a52012-03-05 14:35:53 -08001836 if (stat(filename, &info) < 0)
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001837 return;
1838 if ((fd = open(filename, O_RDONLY)) < 0)
1839 return;
1840 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Xin Lie742c3a2017-03-02 10:59:49 -08001841 if (base == (void *) MAP_FAILED) {
1842 close(fd);
1843 fprintf(stderr, "mmap failure for file %s\n", filename);
1844 progresult = XMLLINT_ERR_RDFILE;
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001845 return;
Xin Lie742c3a2017-03-02 10:59:49 -08001846 }
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001847
1848 reader = xmlReaderForMemory(base, info.st_size, filename,
1849 NULL, options);
1850 } else
1851#endif
1852 reader = xmlReaderForFile(filename, NULL, options);
1853#ifdef LIBXML_PATTERN_ENABLED
1854 if (pattern != NULL) {
1855 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
1856 if (patternc == NULL) {
1857 xmlGenericError(xmlGenericErrorContext,
1858 "Pattern %s failed to compile\n", pattern);
1859 progresult = XMLLINT_ERR_SCHEMAPAT;
1860 pattern = NULL;
1861 }
1862 }
1863 if (patternc != NULL) {
1864 patstream = xmlPatternGetStreamCtxt(patternc);
1865 if (patstream != NULL) {
1866 ret = xmlStreamPush(patstream, NULL, NULL);
1867 if (ret < 0) {
1868 fprintf(stderr, "xmlStreamPush() failure\n");
1869 xmlFreeStreamCtxt(patstream);
1870 patstream = NULL;
1871 }
1872 }
1873 }
1874#endif
1875
1876
1877 if (reader != NULL) {
1878#ifdef LIBXML_VALID_ENABLED
1879 if (valid)
1880 xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
1881 else
1882#endif /* LIBXML_VALID_ENABLED */
Selim Gurun94442ad2013-12-30 18:23:42 -08001883 if (loaddtd)
1884 xmlTextReaderSetParserProp(reader, XML_PARSER_LOADDTD, 1);
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001885#ifdef LIBXML_SCHEMAS_ENABLED
1886 if (relaxng != NULL) {
1887 if ((timing) && (!repeat)) {
1888 startTimer();
1889 }
1890 ret = xmlTextReaderRelaxNGValidate(reader, relaxng);
1891 if (ret < 0) {
1892 xmlGenericError(xmlGenericErrorContext,
1893 "Relax-NG schema %s failed to compile\n", relaxng);
1894 progresult = XMLLINT_ERR_SCHEMACOMP;
1895 relaxng = NULL;
1896 }
1897 if ((timing) && (!repeat)) {
1898 endTimer("Compiling the schemas");
1899 }
1900 }
1901 if (schema != NULL) {
1902 if ((timing) && (!repeat)) {
1903 startTimer();
1904 }
1905 ret = xmlTextReaderSchemaValidate(reader, schema);
1906 if (ret < 0) {
1907 xmlGenericError(xmlGenericErrorContext,
1908 "XSD schema %s failed to compile\n", schema);
1909 progresult = XMLLINT_ERR_SCHEMACOMP;
1910 schema = NULL;
1911 }
1912 if ((timing) && (!repeat)) {
1913 endTimer("Compiling the schemas");
1914 }
1915 }
1916#endif
1917
1918 /*
1919 * Process all nodes in sequence
1920 */
1921 if ((timing) && (!repeat)) {
1922 startTimer();
1923 }
1924 ret = xmlTextReaderRead(reader);
1925 while (ret == 1) {
1926 if ((debug)
1927#ifdef LIBXML_PATTERN_ENABLED
1928 || (patternc)
1929#endif
1930 )
1931 processNode(reader);
1932 ret = xmlTextReaderRead(reader);
1933 }
1934 if ((timing) && (!repeat)) {
1935#ifdef LIBXML_SCHEMAS_ENABLED
1936 if (relaxng != NULL)
1937 endTimer("Parsing and validating");
1938 else
1939#endif
1940#ifdef LIBXML_VALID_ENABLED
1941 if (valid)
1942 endTimer("Parsing and validating");
1943 else
1944#endif
1945 endTimer("Parsing");
1946 }
1947
1948#ifdef LIBXML_VALID_ENABLED
1949 if (valid) {
1950 if (xmlTextReaderIsValid(reader) != 1) {
1951 xmlGenericError(xmlGenericErrorContext,
1952 "Document %s does not validate\n", filename);
1953 progresult = XMLLINT_ERR_VALID;
1954 }
1955 }
1956#endif /* LIBXML_VALID_ENABLED */
1957#ifdef LIBXML_SCHEMAS_ENABLED
1958 if ((relaxng != NULL) || (schema != NULL)) {
1959 if (xmlTextReaderIsValid(reader) != 1) {
1960 fprintf(stderr, "%s fails to validate\n", filename);
1961 progresult = XMLLINT_ERR_VALID;
1962 } else {
1963 fprintf(stderr, "%s validates\n", filename);
1964 }
1965 }
1966#endif
1967 /*
1968 * Done, cleanup and status
1969 */
1970 xmlFreeTextReader(reader);
1971 if (ret != 0) {
1972 fprintf(stderr, "%s : failed to parse\n", filename);
1973 progresult = XMLLINT_ERR_UNCLASS;
1974 }
1975 } else {
1976 fprintf(stderr, "Unable to open %s\n", filename);
1977 progresult = XMLLINT_ERR_UNCLASS;
1978 }
1979#ifdef LIBXML_PATTERN_ENABLED
1980 if (patstream != NULL) {
1981 xmlFreeStreamCtxt(patstream);
1982 patstream = NULL;
1983 }
1984#endif
Selim Gurun94442ad2013-12-30 18:23:42 -08001985#ifdef HAVE_MMAP
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08001986 if (memory) {
1987 xmlFreeParserInputBuffer(input);
1988 munmap((char *) base, info.st_size);
1989 close(fd);
1990 }
1991#endif
1992}
1993
1994static void walkDoc(xmlDocPtr doc) {
1995 xmlTextReaderPtr reader;
1996 int ret;
1997
1998#ifdef LIBXML_PATTERN_ENABLED
1999 xmlNodePtr root;
2000 const xmlChar *namespaces[22];
2001 int i;
2002 xmlNsPtr ns;
2003
2004 root = xmlDocGetRootElement(doc);
Xin Lie742c3a2017-03-02 10:59:49 -08002005 if (root == NULL ) {
2006 xmlGenericError(xmlGenericErrorContext,
2007 "Document does not have a root element");
2008 progresult = XMLLINT_ERR_UNCLASS;
2009 return;
2010 }
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002011 for (ns = root->nsDef, i = 0;ns != NULL && i < 20;ns=ns->next) {
2012 namespaces[i++] = ns->href;
2013 namespaces[i++] = ns->prefix;
2014 }
2015 namespaces[i++] = NULL;
Selim Gurundf143a52012-03-05 14:35:53 -08002016 namespaces[i] = NULL;
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002017
2018 if (pattern != NULL) {
2019 patternc = xmlPatterncompile((const xmlChar *) pattern, doc->dict,
2020 0, &namespaces[0]);
2021 if (patternc == NULL) {
2022 xmlGenericError(xmlGenericErrorContext,
2023 "Pattern %s failed to compile\n", pattern);
2024 progresult = XMLLINT_ERR_SCHEMAPAT;
2025 pattern = NULL;
2026 }
2027 }
2028 if (patternc != NULL) {
2029 patstream = xmlPatternGetStreamCtxt(patternc);
2030 if (patstream != NULL) {
2031 ret = xmlStreamPush(patstream, NULL, NULL);
2032 if (ret < 0) {
2033 fprintf(stderr, "xmlStreamPush() failure\n");
2034 xmlFreeStreamCtxt(patstream);
2035 patstream = NULL;
2036 }
2037 }
2038 }
2039#endif /* LIBXML_PATTERN_ENABLED */
2040 reader = xmlReaderWalker(doc);
2041 if (reader != NULL) {
2042 if ((timing) && (!repeat)) {
2043 startTimer();
2044 }
2045 ret = xmlTextReaderRead(reader);
2046 while (ret == 1) {
2047 if ((debug)
2048#ifdef LIBXML_PATTERN_ENABLED
2049 || (patternc)
2050#endif
2051 )
2052 processNode(reader);
2053 ret = xmlTextReaderRead(reader);
2054 }
2055 if ((timing) && (!repeat)) {
2056 endTimer("walking through the doc");
2057 }
2058 xmlFreeTextReader(reader);
2059 if (ret != 0) {
2060 fprintf(stderr, "failed to walk through the doc\n");
2061 progresult = XMLLINT_ERR_UNCLASS;
2062 }
2063 } else {
2064 fprintf(stderr, "Failed to crate a reader from the document\n");
2065 progresult = XMLLINT_ERR_UNCLASS;
2066 }
2067#ifdef LIBXML_PATTERN_ENABLED
2068 if (patstream != NULL) {
2069 xmlFreeStreamCtxt(patstream);
2070 patstream = NULL;
2071 }
2072#endif
2073}
2074#endif /* LIBXML_READER_ENABLED */
2075
Selim Gurundf143a52012-03-05 14:35:53 -08002076#ifdef LIBXML_XPATH_ENABLED
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002077/************************************************************************
Selim Gurundf143a52012-03-05 14:35:53 -08002078 * *
2079 * XPath Query *
2080 * *
2081 ************************************************************************/
2082
2083static void doXPathDump(xmlXPathObjectPtr cur) {
2084 switch(cur->type) {
2085 case XPATH_NODESET: {
2086 int i;
2087 xmlNodePtr node;
2088#ifdef LIBXML_OUTPUT_ENABLED
2089 xmlSaveCtxtPtr ctxt;
2090
Selim Gurun94442ad2013-12-30 18:23:42 -08002091 if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr <= 0)) {
Selim Gurundf143a52012-03-05 14:35:53 -08002092 fprintf(stderr, "XPath set is empty\n");
2093 progresult = XMLLINT_ERR_XPATH;
2094 break;
2095 }
2096 ctxt = xmlSaveToFd(1, NULL, 0);
2097 if (ctxt == NULL) {
2098 fprintf(stderr, "Out of memory for XPath\n");
2099 progresult = XMLLINT_ERR_MEM;
2100 return;
2101 }
2102 for (i = 0;i < cur->nodesetval->nodeNr;i++) {
2103 node = cur->nodesetval->nodeTab[i];
2104 xmlSaveTree(ctxt, node);
2105 }
2106 xmlSaveClose(ctxt);
2107#else
2108 printf("xpath returned %d nodes\n", cur->nodesetval->nodeNr);
2109#endif
2110 break;
2111 }
2112 case XPATH_BOOLEAN:
2113 if (cur->boolval) printf("true");
2114 else printf("false");
2115 break;
2116 case XPATH_NUMBER:
2117 switch (xmlXPathIsInf(cur->floatval)) {
2118 case 1:
2119 printf("Infinity");
2120 break;
2121 case -1:
2122 printf("-Infinity");
2123 break;
2124 default:
2125 if (xmlXPathIsNaN(cur->floatval)) {
2126 printf("NaN");
2127 } else {
2128 printf("%0g", cur->floatval);
2129 }
2130 }
2131 break;
2132 case XPATH_STRING:
2133 printf("%s", (const char *) cur->stringval);
2134 break;
2135 case XPATH_UNDEFINED:
2136 fprintf(stderr, "XPath Object is uninitialized\n");
2137 progresult = XMLLINT_ERR_XPATH;
2138 break;
2139 default:
2140 fprintf(stderr, "XPath object of unexpected type\n");
2141 progresult = XMLLINT_ERR_XPATH;
2142 break;
2143 }
2144}
2145
2146static void doXPathQuery(xmlDocPtr doc, const char *query) {
2147 xmlXPathContextPtr ctxt;
2148 xmlXPathObjectPtr res;
2149
2150 ctxt = xmlXPathNewContext(doc);
2151 if (ctxt == NULL) {
2152 fprintf(stderr, "Out of memory for XPath\n");
2153 progresult = XMLLINT_ERR_MEM;
2154 return;
2155 }
Selim Gurun94442ad2013-12-30 18:23:42 -08002156 ctxt->node = (xmlNodePtr) doc;
Selim Gurundf143a52012-03-05 14:35:53 -08002157 res = xmlXPathEval(BAD_CAST query, ctxt);
2158 xmlXPathFreeContext(ctxt);
2159
2160 if (res == NULL) {
2161 fprintf(stderr, "XPath evaluation failure\n");
2162 progresult = XMLLINT_ERR_XPATH;
2163 return;
2164 }
2165 doXPathDump(res);
2166 xmlXPathFreeObject(res);
2167}
2168#endif /* LIBXML_XPATH_ENABLED */
2169
2170/************************************************************************
2171 * *
2172 * Tree Test processing *
2173 * *
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002174 ************************************************************************/
2175static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
2176 xmlDocPtr doc = NULL;
2177#ifdef LIBXML_TREE_ENABLED
2178 xmlDocPtr tmp;
2179#endif /* LIBXML_TREE_ENABLED */
2180
2181 if ((timing) && (!repeat))
2182 startTimer();
Selim Gurundf143a52012-03-05 14:35:53 -08002183
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002184
2185#ifdef LIBXML_TREE_ENABLED
2186 if (filename == NULL) {
2187 if (generate) {
2188 xmlNodePtr n;
2189
2190 doc = xmlNewDoc(BAD_CAST "1.0");
2191 n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL);
2192 xmlNodeSetContent(n, BAD_CAST "abc");
2193 xmlDocSetRootElement(doc, n);
2194 }
2195 }
2196#endif /* LIBXML_TREE_ENABLED */
2197#ifdef LIBXML_HTML_ENABLED
2198#ifdef LIBXML_PUSH_ENABLED
2199 else if ((html) && (push)) {
2200 FILE *f;
2201
2202#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2203 f = fopen(filename, "rb");
Xin Lie742c3a2017-03-02 10:59:49 -08002204#elif defined(__OS400__)
2205 f = fopen(filename, "rb");
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002206#else
2207 f = fopen(filename, "r");
2208#endif
2209 if (f != NULL) {
Selim Gurun94442ad2013-12-30 18:23:42 -08002210 int res;
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002211 char chars[4096];
2212 htmlParserCtxtPtr ctxt;
2213
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002214 res = fread(chars, 1, 4, f);
2215 if (res > 0) {
2216 ctxt = htmlCreatePushParserCtxt(NULL, NULL,
2217 chars, res, filename, XML_CHAR_ENCODING_NONE);
Xin Lie742c3a2017-03-02 10:59:49 -08002218 xmlCtxtUseOptions(ctxt, options);
Selim Gurun94442ad2013-12-30 18:23:42 -08002219 while ((res = fread(chars, 1, pushsize, f)) > 0) {
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002220 htmlParseChunk(ctxt, chars, res, 0);
2221 }
2222 htmlParseChunk(ctxt, chars, 0, 1);
2223 doc = ctxt->myDoc;
2224 htmlFreeParserCtxt(ctxt);
2225 }
2226 fclose(f);
2227 }
2228 }
2229#endif /* LIBXML_PUSH_ENABLED */
Selim Gurun94442ad2013-12-30 18:23:42 -08002230#ifdef HAVE_MMAP
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002231 else if ((html) && (memory)) {
2232 int fd;
2233 struct stat info;
2234 const char *base;
Selim Gurundf143a52012-03-05 14:35:53 -08002235 if (stat(filename, &info) < 0)
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002236 return;
2237 if ((fd = open(filename, O_RDONLY)) < 0)
2238 return;
2239 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Xin Lie742c3a2017-03-02 10:59:49 -08002240 if (base == (void *) MAP_FAILED) {
2241 close(fd);
2242 fprintf(stderr, "mmap failure for file %s\n", filename);
2243 progresult = XMLLINT_ERR_RDFILE;
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002244 return;
Xin Lie742c3a2017-03-02 10:59:49 -08002245 }
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002246
2247 doc = htmlReadMemory((char *) base, info.st_size, filename,
2248 NULL, options);
Selim Gurundf143a52012-03-05 14:35:53 -08002249
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002250 munmap((char *) base, info.st_size);
2251 close(fd);
2252 }
2253#endif
2254 else if (html) {
2255 doc = htmlReadFile(filename, NULL, options);
2256 }
2257#endif /* LIBXML_HTML_ENABLED */
2258 else {
2259#ifdef LIBXML_PUSH_ENABLED
2260 /*
2261 * build an XML tree from a string;
2262 */
2263 if (push) {
2264 FILE *f;
2265
2266 /* '-' Usually means stdin -<sven@zen.org> */
2267 if ((filename[0] == '-') && (filename[1] == 0)) {
2268 f = stdin;
2269 } else {
2270#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2271 f = fopen(filename, "rb");
Xin Lie742c3a2017-03-02 10:59:49 -08002272#elif defined(__OS400__)
2273 f = fopen(filename, "rb");
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002274#else
2275 f = fopen(filename, "r");
2276#endif
2277 }
2278 if (f != NULL) {
2279 int ret;
2280 int res, size = 1024;
2281 char chars[1024];
2282 xmlParserCtxtPtr ctxt;
2283
2284 /* if (repeat) size = 1024; */
2285 res = fread(chars, 1, 4, f);
2286 if (res > 0) {
2287 ctxt = xmlCreatePushParserCtxt(NULL, NULL,
2288 chars, res, filename);
2289 xmlCtxtUseOptions(ctxt, options);
2290 while ((res = fread(chars, 1, size, f)) > 0) {
2291 xmlParseChunk(ctxt, chars, res, 0);
2292 }
2293 xmlParseChunk(ctxt, chars, 0, 1);
2294 doc = ctxt->myDoc;
2295 ret = ctxt->wellFormed;
2296 xmlFreeParserCtxt(ctxt);
2297 if (!ret) {
2298 xmlFreeDoc(doc);
2299 doc = NULL;
2300 }
2301 }
Selim Gurundf143a52012-03-05 14:35:53 -08002302 if (f != stdin)
2303 fclose(f);
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002304 }
2305 } else
2306#endif /* LIBXML_PUSH_ENABLED */
2307 if (testIO) {
2308 if ((filename[0] == '-') && (filename[1] == 0)) {
2309 doc = xmlReadFd(0, NULL, NULL, options);
2310 } else {
2311 FILE *f;
2312
2313#if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
2314 f = fopen(filename, "rb");
Xin Lie742c3a2017-03-02 10:59:49 -08002315#elif defined(__OS400__)
2316 f = fopen(filename, "rb");
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002317#else
2318 f = fopen(filename, "r");
2319#endif
2320 if (f != NULL) {
2321 if (rectxt == NULL)
2322 doc = xmlReadIO((xmlInputReadCallback) myRead,
2323 (xmlInputCloseCallback) myClose, f,
2324 filename, NULL, options);
2325 else
2326 doc = xmlCtxtReadIO(rectxt,
2327 (xmlInputReadCallback) myRead,
2328 (xmlInputCloseCallback) myClose, f,
2329 filename, NULL, options);
2330 } else
2331 doc = NULL;
2332 }
2333 } else if (htmlout) {
2334 xmlParserCtxtPtr ctxt;
2335
2336 if (rectxt == NULL)
2337 ctxt = xmlNewParserCtxt();
2338 else
2339 ctxt = rectxt;
Selim Gurundf143a52012-03-05 14:35:53 -08002340 if (ctxt == NULL) {
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002341 doc = NULL;
2342 } else {
2343 ctxt->sax->error = xmlHTMLError;
2344 ctxt->sax->warning = xmlHTMLWarning;
2345 ctxt->vctxt.error = xmlHTMLValidityError;
2346 ctxt->vctxt.warning = xmlHTMLValidityWarning;
2347
2348 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
2349
2350 if (rectxt == NULL)
2351 xmlFreeParserCtxt(ctxt);
2352 }
Selim Gurun94442ad2013-12-30 18:23:42 -08002353#ifdef HAVE_MMAP
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002354 } else if (memory) {
2355 int fd;
2356 struct stat info;
2357 const char *base;
Selim Gurundf143a52012-03-05 14:35:53 -08002358 if (stat(filename, &info) < 0)
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002359 return;
2360 if ((fd = open(filename, O_RDONLY)) < 0)
2361 return;
2362 base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
Xin Lie742c3a2017-03-02 10:59:49 -08002363 if (base == (void *) MAP_FAILED) {
2364 close(fd);
2365 fprintf(stderr, "mmap failure for file %s\n", filename);
2366 progresult = XMLLINT_ERR_RDFILE;
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002367 return;
Xin Lie742c3a2017-03-02 10:59:49 -08002368 }
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002369
2370 if (rectxt == NULL)
2371 doc = xmlReadMemory((char *) base, info.st_size,
2372 filename, NULL, options);
2373 else
2374 doc = xmlCtxtReadMemory(rectxt, (char *) base, info.st_size,
2375 filename, NULL, options);
Selim Gurundf143a52012-03-05 14:35:53 -08002376
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002377 munmap((char *) base, info.st_size);
2378 close(fd);
2379#endif
2380#ifdef LIBXML_VALID_ENABLED
2381 } else if (valid) {
2382 xmlParserCtxtPtr ctxt = NULL;
2383
2384 if (rectxt == NULL)
2385 ctxt = xmlNewParserCtxt();
2386 else
2387 ctxt = rectxt;
Selim Gurundf143a52012-03-05 14:35:53 -08002388 if (ctxt == NULL) {
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002389 doc = NULL;
2390 } else {
2391 doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
2392
2393 if (ctxt->valid == 0)
2394 progresult = XMLLINT_ERR_RDFILE;
2395 if (rectxt == NULL)
2396 xmlFreeParserCtxt(ctxt);
2397 }
2398#endif /* LIBXML_VALID_ENABLED */
2399 } else {
2400 if (rectxt != NULL)
2401 doc = xmlCtxtReadFile(rectxt, filename, NULL, options);
2402 else {
2403#ifdef LIBXML_SAX1_ENABLED
2404 if (sax1)
2405 doc = xmlParseFile(filename);
2406 else
2407#endif /* LIBXML_SAX1_ENABLED */
2408 doc = xmlReadFile(filename, NULL, options);
2409 }
2410 }
2411 }
2412
2413 /*
2414 * If we don't have a document we might as well give up. Do we
2415 * want an error message here? <sven@zen.org> */
2416 if (doc == NULL) {
2417 progresult = XMLLINT_ERR_UNCLASS;
2418 return;
2419 }
2420
2421 if ((timing) && (!repeat)) {
2422 endTimer("Parsing");
2423 }
2424
2425 /*
2426 * Remove DOCTYPE nodes
2427 */
2428 if (dropdtd) {
2429 xmlDtdPtr dtd;
2430
2431 dtd = xmlGetIntSubset(doc);
2432 if (dtd != NULL) {
2433 xmlUnlinkNode((xmlNodePtr)dtd);
2434 xmlFreeDtd(dtd);
2435 }
2436 }
2437
2438#ifdef LIBXML_XINCLUDE_ENABLED
2439 if (xinclude) {
2440 if ((timing) && (!repeat)) {
2441 startTimer();
2442 }
2443 if (xmlXIncludeProcessFlags(doc, options) < 0)
2444 progresult = XMLLINT_ERR_UNCLASS;
2445 if ((timing) && (!repeat)) {
2446 endTimer("Xinclude processing");
2447 }
2448 }
2449#endif
2450
Selim Gurundf143a52012-03-05 14:35:53 -08002451#ifdef LIBXML_XPATH_ENABLED
2452 if (xpathquery != NULL) {
2453 doXPathQuery(doc, xpathquery);
2454 }
2455#endif
2456
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002457#ifdef LIBXML_DEBUG_ENABLED
2458#ifdef LIBXML_XPATH_ENABLED
2459 /*
2460 * shell interaction
2461 */
2462 if (shell) {
2463 xmlXPathOrderDocElems(doc);
2464 xmlShell(doc, filename, xmlShellReadline, stdout);
2465 }
2466#endif
2467#endif
2468
2469#ifdef LIBXML_TREE_ENABLED
2470 /*
2471 * test intermediate copy if needed.
2472 */
2473 if (copy) {
2474 tmp = doc;
2475 if (timing) {
2476 startTimer();
2477 }
2478 doc = xmlCopyDoc(doc, 1);
2479 if (timing) {
2480 endTimer("Copying");
2481 }
2482 if (timing) {
2483 startTimer();
2484 }
2485 xmlFreeDoc(tmp);
2486 if (timing) {
2487 endTimer("Freeing original");
2488 }
2489 }
2490#endif /* LIBXML_TREE_ENABLED */
2491
2492#ifdef LIBXML_VALID_ENABLED
2493 if ((insert) && (!html)) {
2494 const xmlChar* list[256];
2495 int nb, i;
2496 xmlNodePtr node;
2497
2498 if (doc->children != NULL) {
2499 node = doc->children;
2500 while ((node != NULL) && (node->last == NULL)) node = node->next;
2501 if (node != NULL) {
2502 nb = xmlValidGetValidElements(node->last, NULL, list, 256);
2503 if (nb < 0) {
2504 fprintf(stderr, "could not get valid list of elements\n");
2505 } else if (nb == 0) {
2506 fprintf(stderr, "No element can be inserted under root\n");
2507 } else {
2508 fprintf(stderr, "%d element types can be inserted under root:\n",
2509 nb);
2510 for (i = 0;i < nb;i++) {
2511 fprintf(stderr, "%s\n", (char *) list[i]);
2512 }
2513 }
2514 }
Selim Gurundf143a52012-03-05 14:35:53 -08002515 }
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002516 }else
2517#endif /* LIBXML_VALID_ENABLED */
2518#ifdef LIBXML_READER_ENABLED
2519 if (walker) {
2520 walkDoc(doc);
2521 }
2522#endif /* LIBXML_READER_ENABLED */
2523#ifdef LIBXML_OUTPUT_ENABLED
2524 if (noout == 0) {
2525 int ret;
2526
2527 /*
2528 * print it.
2529 */
2530#ifdef LIBXML_DEBUG_ENABLED
2531 if (!debug) {
2532#endif
2533 if ((timing) && (!repeat)) {
2534 startTimer();
2535 }
2536#ifdef LIBXML_HTML_ENABLED
2537 if ((html) && (!xmlout)) {
2538 if (compress) {
2539 htmlSaveFile(output ? output : "-", doc);
2540 }
2541 else if (encoding != NULL) {
Selim Gurundf143a52012-03-05 14:35:53 -08002542 if (format == 1) {
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002543 htmlSaveFileFormat(output ? output : "-", doc, encoding, 1);
2544 }
2545 else {
2546 htmlSaveFileFormat(output ? output : "-", doc, encoding, 0);
2547 }
2548 }
Selim Gurundf143a52012-03-05 14:35:53 -08002549 else if (format == 1) {
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002550 htmlSaveFileFormat(output ? output : "-", doc, NULL, 1);
2551 }
2552 else {
2553 FILE *out;
2554 if (output == NULL)
2555 out = stdout;
2556 else {
2557 out = fopen(output,"wb");
2558 }
2559 if (out != NULL) {
2560 if (htmlDocDump(out, doc) < 0)
2561 progresult = XMLLINT_ERR_OUT;
2562
2563 if (output != NULL)
2564 fclose(out);
2565 } else {
2566 fprintf(stderr, "failed to open %s\n", output);
2567 progresult = XMLLINT_ERR_OUT;
2568 }
2569 }
2570 if ((timing) && (!repeat)) {
2571 endTimer("Saving");
2572 }
2573 } else
2574#endif
2575#ifdef LIBXML_C14N_ENABLED
2576 if (canonical) {
2577 xmlChar *result = NULL;
2578 int size;
2579
Selim Gurundf143a52012-03-05 14:35:53 -08002580 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_0, NULL, 1, &result);
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002581 if (size >= 0) {
Selim Gurundf143a52012-03-05 14:35:53 -08002582 if (write(1, result, size) == -1) {
2583 fprintf(stderr, "Can't write data\n");
2584 }
2585 xmlFree(result);
2586 } else {
2587 fprintf(stderr, "Failed to canonicalize\n");
2588 progresult = XMLLINT_ERR_OUT;
2589 }
Xin Lie742c3a2017-03-02 10:59:49 -08002590 } else if (canonical_11) {
Selim Gurundf143a52012-03-05 14:35:53 -08002591 xmlChar *result = NULL;
2592 int size;
2593
2594 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_1, NULL, 1, &result);
2595 if (size >= 0) {
2596 if (write(1, result, size) == -1) {
2597 fprintf(stderr, "Can't write data\n");
2598 }
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002599 xmlFree(result);
2600 } else {
2601 fprintf(stderr, "Failed to canonicalize\n");
2602 progresult = XMLLINT_ERR_OUT;
2603 }
2604 } else
2605 if (exc_canonical) {
2606 xmlChar *result = NULL;
2607 int size;
2608
Selim Gurundf143a52012-03-05 14:35:53 -08002609 size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_EXCLUSIVE_1_0, NULL, 1, &result);
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002610 if (size >= 0) {
Selim Gurundf143a52012-03-05 14:35:53 -08002611 if (write(1, result, size) == -1) {
2612 fprintf(stderr, "Can't write data\n");
2613 }
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002614 xmlFree(result);
2615 } else {
2616 fprintf(stderr, "Failed to canonicalize\n");
2617 progresult = XMLLINT_ERR_OUT;
2618 }
2619 } else
2620#endif
Selim Gurun94442ad2013-12-30 18:23:42 -08002621#ifdef HAVE_MMAP
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002622 if (memory) {
2623 xmlChar *result;
2624 int len;
2625
2626 if (encoding != NULL) {
Selim Gurundf143a52012-03-05 14:35:53 -08002627 if (format == 1) {
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002628 xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
Selim Gurundf143a52012-03-05 14:35:53 -08002629 } else {
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002630 xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
2631 }
2632 } else {
Selim Gurundf143a52012-03-05 14:35:53 -08002633 if (format == 1)
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002634 xmlDocDumpFormatMemory(doc, &result, &len, 1);
2635 else
2636 xmlDocDumpMemory(doc, &result, &len);
2637 }
2638 if (result == NULL) {
2639 fprintf(stderr, "Failed to save\n");
2640 progresult = XMLLINT_ERR_OUT;
2641 } else {
Selim Gurundf143a52012-03-05 14:35:53 -08002642 if (write(1, result, len) == -1) {
2643 fprintf(stderr, "Can't write data\n");
2644 }
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002645 xmlFree(result);
2646 }
2647
2648 } else
Selim Gurun94442ad2013-12-30 18:23:42 -08002649#endif /* HAVE_MMAP */
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002650 if (compress) {
2651 xmlSaveFile(output ? output : "-", doc);
2652 } else if (oldout) {
2653 if (encoding != NULL) {
Selim Gurundf143a52012-03-05 14:35:53 -08002654 if (format == 1) {
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002655 ret = xmlSaveFormatFileEnc(output ? output : "-", doc,
2656 encoding, 1);
2657 }
2658 else {
2659 ret = xmlSaveFileEnc(output ? output : "-", doc,
2660 encoding);
2661 }
2662 if (ret < 0) {
2663 fprintf(stderr, "failed save to %s\n",
2664 output ? output : "-");
2665 progresult = XMLLINT_ERR_OUT;
2666 }
Selim Gurundf143a52012-03-05 14:35:53 -08002667 } else if (format == 1) {
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002668 ret = xmlSaveFormatFile(output ? output : "-", doc, 1);
2669 if (ret < 0) {
2670 fprintf(stderr, "failed save to %s\n",
2671 output ? output : "-");
2672 progresult = XMLLINT_ERR_OUT;
2673 }
2674 } else {
2675 FILE *out;
2676 if (output == NULL)
2677 out = stdout;
2678 else {
2679 out = fopen(output,"wb");
2680 }
2681 if (out != NULL) {
2682 if (xmlDocDump(out, doc) < 0)
2683 progresult = XMLLINT_ERR_OUT;
2684
2685 if (output != NULL)
2686 fclose(out);
2687 } else {
2688 fprintf(stderr, "failed to open %s\n", output);
2689 progresult = XMLLINT_ERR_OUT;
2690 }
2691 }
2692 } else {
2693 xmlSaveCtxtPtr ctxt;
2694 int saveOpts = 0;
2695
Selim Gurundf143a52012-03-05 14:35:53 -08002696 if (format == 1)
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002697 saveOpts |= XML_SAVE_FORMAT;
Selim Gurundf143a52012-03-05 14:35:53 -08002698 else if (format == 2)
2699 saveOpts |= XML_SAVE_WSNONSIG;
2700
2701#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
2702 if (xmlout)
2703 saveOpts |= XML_SAVE_AS_XML;
2704#endif
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002705
2706 if (output == NULL)
2707 ctxt = xmlSaveToFd(1, encoding, saveOpts);
2708 else
2709 ctxt = xmlSaveToFilename(output, encoding, saveOpts);
2710
2711 if (ctxt != NULL) {
2712 if (xmlSaveDoc(ctxt, doc) < 0) {
2713 fprintf(stderr, "failed save to %s\n",
2714 output ? output : "-");
2715 progresult = XMLLINT_ERR_OUT;
2716 }
2717 xmlSaveClose(ctxt);
2718 } else {
2719 progresult = XMLLINT_ERR_OUT;
2720 }
2721 }
2722 if ((timing) && (!repeat)) {
2723 endTimer("Saving");
2724 }
2725#ifdef LIBXML_DEBUG_ENABLED
2726 } else {
2727 FILE *out;
2728 if (output == NULL)
2729 out = stdout;
2730 else {
2731 out = fopen(output,"wb");
2732 }
2733 if (out != NULL) {
2734 xmlDebugDumpDocument(out, doc);
2735
2736 if (output != NULL)
2737 fclose(out);
2738 } else {
2739 fprintf(stderr, "failed to open %s\n", output);
2740 progresult = XMLLINT_ERR_OUT;
2741 }
2742 }
2743#endif
2744 }
2745#endif /* LIBXML_OUTPUT_ENABLED */
2746
2747#ifdef LIBXML_VALID_ENABLED
2748 /*
2749 * A posteriori validation test
2750 */
2751 if ((dtdvalid != NULL) || (dtdvalidfpi != NULL)) {
2752 xmlDtdPtr dtd;
2753
2754 if ((timing) && (!repeat)) {
2755 startTimer();
2756 }
2757 if (dtdvalid != NULL)
Selim Gurundf143a52012-03-05 14:35:53 -08002758 dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002759 else
Selim Gurundf143a52012-03-05 14:35:53 -08002760 dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL);
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002761 if ((timing) && (!repeat)) {
2762 endTimer("Parsing DTD");
2763 }
2764 if (dtd == NULL) {
2765 if (dtdvalid != NULL)
2766 xmlGenericError(xmlGenericErrorContext,
2767 "Could not parse DTD %s\n", dtdvalid);
2768 else
2769 xmlGenericError(xmlGenericErrorContext,
2770 "Could not parse DTD %s\n", dtdvalidfpi);
2771 progresult = XMLLINT_ERR_DTD;
2772 } else {
2773 xmlValidCtxtPtr cvp;
2774
2775 if ((cvp = xmlNewValidCtxt()) == NULL) {
2776 xmlGenericError(xmlGenericErrorContext,
2777 "Couldn't allocate validation context\n");
2778 exit(-1);
2779 }
2780 cvp->userData = (void *) stderr;
2781 cvp->error = (xmlValidityErrorFunc) fprintf;
2782 cvp->warning = (xmlValidityWarningFunc) fprintf;
2783
2784 if ((timing) && (!repeat)) {
2785 startTimer();
2786 }
2787 if (!xmlValidateDtd(cvp, doc, dtd)) {
2788 if (dtdvalid != NULL)
2789 xmlGenericError(xmlGenericErrorContext,
2790 "Document %s does not validate against %s\n",
2791 filename, dtdvalid);
2792 else
2793 xmlGenericError(xmlGenericErrorContext,
2794 "Document %s does not validate against %s\n",
2795 filename, dtdvalidfpi);
2796 progresult = XMLLINT_ERR_VALID;
2797 }
2798 if ((timing) && (!repeat)) {
2799 endTimer("Validating against DTD");
2800 }
2801 xmlFreeValidCtxt(cvp);
2802 xmlFreeDtd(dtd);
2803 }
2804 } else if (postvalid) {
2805 xmlValidCtxtPtr cvp;
2806
2807 if ((cvp = xmlNewValidCtxt()) == NULL) {
2808 xmlGenericError(xmlGenericErrorContext,
2809 "Couldn't allocate validation context\n");
2810 exit(-1);
2811 }
2812
2813 if ((timing) && (!repeat)) {
2814 startTimer();
2815 }
2816 cvp->userData = (void *) stderr;
2817 cvp->error = (xmlValidityErrorFunc) fprintf;
2818 cvp->warning = (xmlValidityWarningFunc) fprintf;
2819 if (!xmlValidateDocument(cvp, doc)) {
2820 xmlGenericError(xmlGenericErrorContext,
2821 "Document %s does not validate\n", filename);
2822 progresult = XMLLINT_ERR_VALID;
2823 }
2824 if ((timing) && (!repeat)) {
2825 endTimer("Validating");
2826 }
2827 xmlFreeValidCtxt(cvp);
2828 }
2829#endif /* LIBXML_VALID_ENABLED */
2830#ifdef LIBXML_SCHEMATRON_ENABLED
2831 if (wxschematron != NULL) {
2832 xmlSchematronValidCtxtPtr ctxt;
2833 int ret;
2834 int flag;
2835
2836 if ((timing) && (!repeat)) {
2837 startTimer();
2838 }
2839
2840 if (debug)
2841 flag = XML_SCHEMATRON_OUT_XML;
2842 else
2843 flag = XML_SCHEMATRON_OUT_TEXT;
2844 if (noout)
2845 flag |= XML_SCHEMATRON_OUT_QUIET;
2846 ctxt = xmlSchematronNewValidCtxt(wxschematron, flag);
2847#if 0
2848 xmlSchematronSetValidErrors(ctxt,
2849 (xmlSchematronValidityErrorFunc) fprintf,
2850 (xmlSchematronValidityWarningFunc) fprintf,
2851 stderr);
2852#endif
2853 ret = xmlSchematronValidateDoc(ctxt, doc);
2854 if (ret == 0) {
2855 fprintf(stderr, "%s validates\n", filename);
2856 } else if (ret > 0) {
2857 fprintf(stderr, "%s fails to validate\n", filename);
2858 progresult = XMLLINT_ERR_VALID;
2859 } else {
2860 fprintf(stderr, "%s validation generated an internal error\n",
2861 filename);
2862 progresult = XMLLINT_ERR_VALID;
2863 }
2864 xmlSchematronFreeValidCtxt(ctxt);
2865 if ((timing) && (!repeat)) {
2866 endTimer("Validating");
2867 }
2868 }
2869#endif
2870#ifdef LIBXML_SCHEMAS_ENABLED
2871 if (relaxngschemas != NULL) {
2872 xmlRelaxNGValidCtxtPtr ctxt;
2873 int ret;
2874
2875 if ((timing) && (!repeat)) {
2876 startTimer();
2877 }
2878
2879 ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
2880 xmlRelaxNGSetValidErrors(ctxt,
2881 (xmlRelaxNGValidityErrorFunc) fprintf,
2882 (xmlRelaxNGValidityWarningFunc) fprintf,
2883 stderr);
2884 ret = xmlRelaxNGValidateDoc(ctxt, doc);
2885 if (ret == 0) {
2886 fprintf(stderr, "%s validates\n", filename);
2887 } else if (ret > 0) {
2888 fprintf(stderr, "%s fails to validate\n", filename);
2889 progresult = XMLLINT_ERR_VALID;
2890 } else {
2891 fprintf(stderr, "%s validation generated an internal error\n",
2892 filename);
2893 progresult = XMLLINT_ERR_VALID;
2894 }
2895 xmlRelaxNGFreeValidCtxt(ctxt);
2896 if ((timing) && (!repeat)) {
2897 endTimer("Validating");
2898 }
2899 } else if (wxschemas != NULL) {
2900 xmlSchemaValidCtxtPtr ctxt;
2901 int ret;
2902
2903 if ((timing) && (!repeat)) {
2904 startTimer();
2905 }
2906
2907 ctxt = xmlSchemaNewValidCtxt(wxschemas);
2908 xmlSchemaSetValidErrors(ctxt,
2909 (xmlSchemaValidityErrorFunc) fprintf,
2910 (xmlSchemaValidityWarningFunc) fprintf,
2911 stderr);
2912 ret = xmlSchemaValidateDoc(ctxt, doc);
2913 if (ret == 0) {
2914 fprintf(stderr, "%s validates\n", filename);
2915 } else if (ret > 0) {
2916 fprintf(stderr, "%s fails to validate\n", filename);
2917 progresult = XMLLINT_ERR_VALID;
2918 } else {
2919 fprintf(stderr, "%s validation generated an internal error\n",
2920 filename);
2921 progresult = XMLLINT_ERR_VALID;
2922 }
2923 xmlSchemaFreeValidCtxt(ctxt);
2924 if ((timing) && (!repeat)) {
2925 endTimer("Validating");
2926 }
2927 }
2928#endif
2929
2930#ifdef LIBXML_DEBUG_ENABLED
Patrick Scott60a4c352009-07-09 09:30:54 -04002931#if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002932 if ((debugent) && (!html))
2933 xmlDebugDumpEntities(stderr, doc);
2934#endif
Patrick Scott60a4c352009-07-09 09:30:54 -04002935#endif
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002936
2937 /*
2938 * free it.
2939 */
2940 if ((timing) && (!repeat)) {
2941 startTimer();
2942 }
2943 xmlFreeDoc(doc);
2944 if ((timing) && (!repeat)) {
2945 endTimer("Freeing");
2946 }
2947}
2948
2949/************************************************************************
Selim Gurundf143a52012-03-05 14:35:53 -08002950 * *
2951 * Usage and Main *
2952 * *
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002953 ************************************************************************/
2954
2955static void showVersion(const char *name) {
2956 fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
2957 fprintf(stderr, " compiled with: ");
2958 if (xmlHasFeature(XML_WITH_THREAD)) fprintf(stderr, "Threads ");
2959 if (xmlHasFeature(XML_WITH_TREE)) fprintf(stderr, "Tree ");
2960 if (xmlHasFeature(XML_WITH_OUTPUT)) fprintf(stderr, "Output ");
2961 if (xmlHasFeature(XML_WITH_PUSH)) fprintf(stderr, "Push ");
2962 if (xmlHasFeature(XML_WITH_READER)) fprintf(stderr, "Reader ");
2963 if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(stderr, "Patterns ");
2964 if (xmlHasFeature(XML_WITH_WRITER)) fprintf(stderr, "Writer ");
2965 if (xmlHasFeature(XML_WITH_SAX1)) fprintf(stderr, "SAXv1 ");
Selim Gurundf143a52012-03-05 14:35:53 -08002966 if (xmlHasFeature(XML_WITH_FTP)) fprintf(stderr, "FTP ");
2967 if (xmlHasFeature(XML_WITH_HTTP)) fprintf(stderr, "HTTP ");
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002968 if (xmlHasFeature(XML_WITH_VALID)) fprintf(stderr, "DTDValid ");
Selim Gurundf143a52012-03-05 14:35:53 -08002969 if (xmlHasFeature(XML_WITH_HTML)) fprintf(stderr, "HTML ");
2970 if (xmlHasFeature(XML_WITH_LEGACY)) fprintf(stderr, "Legacy ");
2971 if (xmlHasFeature(XML_WITH_C14N)) fprintf(stderr, "C14N ");
2972 if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(stderr, "Catalog ");
2973 if (xmlHasFeature(XML_WITH_XPATH)) fprintf(stderr, "XPath ");
2974 if (xmlHasFeature(XML_WITH_XPTR)) fprintf(stderr, "XPointer ");
2975 if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(stderr, "XInclude ");
2976 if (xmlHasFeature(XML_WITH_ICONV)) fprintf(stderr, "Iconv ");
Xin Lie742c3a2017-03-02 10:59:49 -08002977 if (xmlHasFeature(XML_WITH_ICU)) fprintf(stderr, "ICU ");
Selim Gurundf143a52012-03-05 14:35:53 -08002978 if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(stderr, "ISO8859X ");
2979 if (xmlHasFeature(XML_WITH_UNICODE)) fprintf(stderr, "Unicode ");
2980 if (xmlHasFeature(XML_WITH_REGEXP)) fprintf(stderr, "Regexps ");
2981 if (xmlHasFeature(XML_WITH_AUTOMATA)) fprintf(stderr, "Automata ");
2982 if (xmlHasFeature(XML_WITH_EXPR)) fprintf(stderr, "Expr ");
2983 if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(stderr, "Schemas ");
2984 if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(stderr, "Schematron ");
2985 if (xmlHasFeature(XML_WITH_MODULES)) fprintf(stderr, "Modules ");
2986 if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(stderr, "Debug ");
2987 if (xmlHasFeature(XML_WITH_DEBUG_MEM)) fprintf(stderr, "MemDebug ");
2988 if (xmlHasFeature(XML_WITH_DEBUG_RUN)) fprintf(stderr, "RunDebug ");
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002989 if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(stderr, "Zlib ");
Selim Gurundf143a52012-03-05 14:35:53 -08002990 if (xmlHasFeature(XML_WITH_LZMA)) fprintf(stderr, "Lzma ");
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08002991 fprintf(stderr, "\n");
2992}
2993
2994static void usage(const char *name) {
2995 printf("Usage : %s [options] XMLfiles ...\n", name);
2996#ifdef LIBXML_OUTPUT_ENABLED
2997 printf("\tParse the XML files and output the result of the parsing\n");
2998#else
2999 printf("\tParse the XML files\n");
3000#endif /* LIBXML_OUTPUT_ENABLED */
3001 printf("\t--version : display the version of the XML library used\n");
3002#ifdef LIBXML_DEBUG_ENABLED
3003 printf("\t--debug : dump a debug tree of the in-memory document\n");
3004 printf("\t--shell : run a navigating shell\n");
3005 printf("\t--debugent : debug the entities defined in the document\n");
3006#else
3007#ifdef LIBXML_READER_ENABLED
3008 printf("\t--debug : dump the nodes content when using --stream\n");
3009#endif /* LIBXML_READER_ENABLED */
3010#endif
3011#ifdef LIBXML_TREE_ENABLED
3012 printf("\t--copy : used to test the internal copy implementation\n");
3013#endif /* LIBXML_TREE_ENABLED */
3014 printf("\t--recover : output what was parsable on broken XML documents\n");
Patrick Scott60a4c352009-07-09 09:30:54 -04003015 printf("\t--huge : remove any internal arbitrary parser limits\n");
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003016 printf("\t--noent : substitute entity references by their value\n");
Selim Gurundf143a52012-03-05 14:35:53 -08003017 printf("\t--noenc : ignore any encoding specified inside the document\n");
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003018 printf("\t--noout : don't output the result tree\n");
3019 printf("\t--path 'paths': provide a set of paths for resources\n");
Xin Lie742c3a2017-03-02 10:59:49 -08003020 printf("\t--load-trace : print trace of all external entities loaded\n");
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003021 printf("\t--nonet : refuse to fetch DTDs or entities over network\n");
3022 printf("\t--nocompact : do not generate compact text nodes\n");
3023 printf("\t--htmlout : output results as HTML\n");
3024 printf("\t--nowrap : do not put HTML doc wrapper\n");
3025#ifdef LIBXML_VALID_ENABLED
3026 printf("\t--valid : validate the document in addition to std well-formed check\n");
3027 printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
3028 printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
3029 printf("\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
3030#endif /* LIBXML_VALID_ENABLED */
3031 printf("\t--timing : print some timings\n");
3032 printf("\t--output file or -o file: save to a given file\n");
3033 printf("\t--repeat : repeat 100 times, for timing or profiling\n");
3034 printf("\t--insert : ad-hoc test for valid insertions\n");
3035#ifdef LIBXML_OUTPUT_ENABLED
3036#ifdef HAVE_ZLIB_H
3037 printf("\t--compress : turn on gzip compression of output\n");
3038#endif
3039#endif /* LIBXML_OUTPUT_ENABLED */
3040#ifdef LIBXML_HTML_ENABLED
3041 printf("\t--html : use the HTML parser\n");
3042 printf("\t--xmlout : force to use the XML serializer when using --html\n");
Selim Gurundf143a52012-03-05 14:35:53 -08003043 printf("\t--nodefdtd : do not default HTML doctype\n");
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003044#endif
3045#ifdef LIBXML_PUSH_ENABLED
3046 printf("\t--push : use the push mode of the parser\n");
Selim Gurun94442ad2013-12-30 18:23:42 -08003047 printf("\t--pushsmall : use the push mode of the parser using tiny increments\n");
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003048#endif /* LIBXML_PUSH_ENABLED */
Selim Gurun94442ad2013-12-30 18:23:42 -08003049#ifdef HAVE_MMAP
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003050 printf("\t--memory : parse from memory\n");
3051#endif
3052 printf("\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n");
3053 printf("\t--nowarning : do not emit warnings from parser/validator\n");
3054 printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
3055 printf("\t--nocdata : replace cdata section with text nodes\n");
3056#ifdef LIBXML_OUTPUT_ENABLED
Xin Lie742c3a2017-03-02 10:59:49 -08003057 printf("\t--format : reformat/reindent the output\n");
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003058 printf("\t--encode encoding : output in the given encoding\n");
3059 printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
Selim Gurundf143a52012-03-05 14:35:53 -08003060 printf("\t--pretty STYLE : pretty-print in a particular style\n");
3061 printf("\t 0 Do not pretty print\n");
3062 printf("\t 1 Format the XML content, as --format\n");
3063 printf("\t 2 Add whitespace inside tags, preserving content\n");
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003064#endif /* LIBXML_OUTPUT_ENABLED */
Selim Gurundf143a52012-03-05 14:35:53 -08003065 printf("\t--c14n : save in W3C canonical format v1.0 (with comments)\n");
3066 printf("\t--c14n11 : save in W3C canonical format v1.1 (with comments)\n");
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003067 printf("\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n");
3068#ifdef LIBXML_C14N_ENABLED
3069#endif /* LIBXML_C14N_ENABLED */
3070 printf("\t--nsclean : remove redundant namespace declarations\n");
3071 printf("\t--testIO : test user I/O support\n");
3072#ifdef LIBXML_CATALOG_ENABLED
3073 printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
3074 printf("\t otherwise XML Catalogs starting from \n");
3075 printf("\t %s are activated by default\n", XML_XML_DEFAULT_CATALOG);
3076 printf("\t--nocatalogs: deactivate all catalogs\n");
3077#endif
3078 printf("\t--auto : generate a small doc on the fly\n");
3079#ifdef LIBXML_XINCLUDE_ENABLED
3080 printf("\t--xinclude : do XInclude processing\n");
3081 printf("\t--noxincludenode : same but do not generate XInclude nodes\n");
Patrick Scott60a4c352009-07-09 09:30:54 -04003082 printf("\t--nofixup-base-uris : do not fixup xml:base uris\n");
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003083#endif
3084 printf("\t--loaddtd : fetch external DTD\n");
3085 printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
3086#ifdef LIBXML_READER_ENABLED
3087 printf("\t--stream : use the streaming interface to process very large files\n");
3088 printf("\t--walker : create a reader and walk though the resulting doc\n");
3089#endif /* LIBXML_READER_ENABLED */
3090#ifdef LIBXML_PATTERN_ENABLED
3091 printf("\t--pattern pattern_value : test the pattern support\n");
3092#endif
3093 printf("\t--chkregister : verify the node registration code\n");
3094#ifdef LIBXML_SCHEMAS_ENABLED
3095 printf("\t--relaxng schema : do RelaxNG validation against the schema\n");
3096 printf("\t--schema schema : do validation against the WXS schema\n");
3097#endif
3098#ifdef LIBXML_SCHEMATRON_ENABLED
3099 printf("\t--schematron schema : do validation against a schematron\n");
3100#endif
3101#ifdef LIBXML_SAX1_ENABLED
3102 printf("\t--sax1: use the old SAX1 interfaces for processing\n");
3103#endif
3104 printf("\t--sax: do not build a tree but work just at the SAX level\n");
Patrick Scott60a4c352009-07-09 09:30:54 -04003105 printf("\t--oldxml10: use XML-1.0 parsing rules before the 5th edition\n");
Selim Gurundf143a52012-03-05 14:35:53 -08003106#ifdef LIBXML_XPATH_ENABLED
Selim Gurun94442ad2013-12-30 18:23:42 -08003107 printf("\t--xpath expr: evaluate the XPath expression, imply --noout\n");
Selim Gurundf143a52012-03-05 14:35:53 -08003108#endif
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003109
3110 printf("\nLibxml project home page: http://xmlsoft.org/\n");
3111 printf("To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
3112}
3113
3114static void registerNode(xmlNodePtr node)
3115{
3116 node->_private = malloc(sizeof(long));
Xin Lie742c3a2017-03-02 10:59:49 -08003117 if (node->_private == NULL) {
3118 fprintf(stderr, "Out of memory in xmllint:registerNode()\n");
3119 exit(XMLLINT_ERR_MEM);
3120 }
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003121 *(long*)node->_private = (long) 0x81726354;
3122 nbregister++;
3123}
3124
3125static void deregisterNode(xmlNodePtr node)
3126{
3127 assert(node->_private != NULL);
3128 assert(*(long*)node->_private == (long) 0x81726354);
3129 free(node->_private);
3130 nbregister--;
3131}
3132
3133int
3134main(int argc, char **argv) {
3135 int i, acount;
3136 int files = 0;
3137 int version = 0;
3138 const char* indent;
Selim Gurundf143a52012-03-05 14:35:53 -08003139
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003140 if (argc <= 1) {
3141 usage(argv[0]);
3142 return(1);
3143 }
3144 LIBXML_TEST_VERSION
3145 for (i = 1; i < argc ; i++) {
3146 if (!strcmp(argv[i], "-"))
3147 break;
3148
3149 if (argv[i][0] != '-')
3150 continue;
3151 if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
3152 debug++;
3153 else
3154#ifdef LIBXML_DEBUG_ENABLED
3155 if ((!strcmp(argv[i], "-shell")) ||
3156 (!strcmp(argv[i], "--shell"))) {
3157 shell++;
3158 noout = 1;
Selim Gurundf143a52012-03-05 14:35:53 -08003159 } else
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003160#endif
3161#ifdef LIBXML_TREE_ENABLED
3162 if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
3163 copy++;
3164 else
3165#endif /* LIBXML_TREE_ENABLED */
3166 if ((!strcmp(argv[i], "-recover")) ||
3167 (!strcmp(argv[i], "--recover"))) {
3168 recovery++;
3169 options |= XML_PARSE_RECOVER;
Patrick Scott60a4c352009-07-09 09:30:54 -04003170 } else if ((!strcmp(argv[i], "-huge")) ||
3171 (!strcmp(argv[i], "--huge"))) {
3172 options |= XML_PARSE_HUGE;
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003173 } else if ((!strcmp(argv[i], "-noent")) ||
3174 (!strcmp(argv[i], "--noent"))) {
3175 noent++;
3176 options |= XML_PARSE_NOENT;
Selim Gurundf143a52012-03-05 14:35:53 -08003177 } else if ((!strcmp(argv[i], "-noenc")) ||
3178 (!strcmp(argv[i], "--noenc"))) {
3179 noenc++;
3180 options |= XML_PARSE_IGNORE_ENC;
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003181 } else if ((!strcmp(argv[i], "-nsclean")) ||
3182 (!strcmp(argv[i], "--nsclean"))) {
3183 options |= XML_PARSE_NSCLEAN;
3184 } else if ((!strcmp(argv[i], "-nocdata")) ||
3185 (!strcmp(argv[i], "--nocdata"))) {
3186 options |= XML_PARSE_NOCDATA;
3187 } else if ((!strcmp(argv[i], "-nodict")) ||
3188 (!strcmp(argv[i], "--nodict"))) {
3189 options |= XML_PARSE_NODICT;
3190 } else if ((!strcmp(argv[i], "-version")) ||
3191 (!strcmp(argv[i], "--version"))) {
3192 showVersion(argv[0]);
3193 version = 1;
3194 } else if ((!strcmp(argv[i], "-noout")) ||
3195 (!strcmp(argv[i], "--noout")))
3196 noout++;
3197#ifdef LIBXML_OUTPUT_ENABLED
3198 else if ((!strcmp(argv[i], "-o")) ||
3199 (!strcmp(argv[i], "-output")) ||
3200 (!strcmp(argv[i], "--output"))) {
3201 i++;
3202 output = argv[i];
3203 }
3204#endif /* LIBXML_OUTPUT_ENABLED */
3205 else if ((!strcmp(argv[i], "-htmlout")) ||
3206 (!strcmp(argv[i], "--htmlout")))
3207 htmlout++;
3208 else if ((!strcmp(argv[i], "-nowrap")) ||
3209 (!strcmp(argv[i], "--nowrap")))
3210 nowrap++;
3211#ifdef LIBXML_HTML_ENABLED
3212 else if ((!strcmp(argv[i], "-html")) ||
3213 (!strcmp(argv[i], "--html"))) {
3214 html++;
3215 }
3216 else if ((!strcmp(argv[i], "-xmlout")) ||
3217 (!strcmp(argv[i], "--xmlout"))) {
3218 xmlout++;
Selim Gurundf143a52012-03-05 14:35:53 -08003219 } else if ((!strcmp(argv[i], "-nodefdtd")) ||
3220 (!strcmp(argv[i], "--nodefdtd"))) {
3221 nodefdtd++;
3222 options |= HTML_PARSE_NODEFDTD;
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003223 }
3224#endif /* LIBXML_HTML_ENABLED */
3225 else if ((!strcmp(argv[i], "-loaddtd")) ||
3226 (!strcmp(argv[i], "--loaddtd"))) {
3227 loaddtd++;
3228 options |= XML_PARSE_DTDLOAD;
3229 } else if ((!strcmp(argv[i], "-dtdattr")) ||
3230 (!strcmp(argv[i], "--dtdattr"))) {
3231 loaddtd++;
3232 dtdattrs++;
3233 options |= XML_PARSE_DTDATTR;
3234 }
3235#ifdef LIBXML_VALID_ENABLED
3236 else if ((!strcmp(argv[i], "-valid")) ||
3237 (!strcmp(argv[i], "--valid"))) {
3238 valid++;
3239 options |= XML_PARSE_DTDVALID;
3240 } else if ((!strcmp(argv[i], "-postvalid")) ||
3241 (!strcmp(argv[i], "--postvalid"))) {
3242 postvalid++;
3243 loaddtd++;
3244 options |= XML_PARSE_DTDLOAD;
3245 } else if ((!strcmp(argv[i], "-dtdvalid")) ||
3246 (!strcmp(argv[i], "--dtdvalid"))) {
3247 i++;
3248 dtdvalid = argv[i];
3249 loaddtd++;
3250 options |= XML_PARSE_DTDLOAD;
3251 } else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3252 (!strcmp(argv[i], "--dtdvalidfpi"))) {
3253 i++;
3254 dtdvalidfpi = argv[i];
3255 loaddtd++;
3256 options |= XML_PARSE_DTDLOAD;
3257 }
3258#endif /* LIBXML_VALID_ENABLED */
3259 else if ((!strcmp(argv[i], "-dropdtd")) ||
3260 (!strcmp(argv[i], "--dropdtd")))
3261 dropdtd++;
3262 else if ((!strcmp(argv[i], "-insert")) ||
3263 (!strcmp(argv[i], "--insert")))
3264 insert++;
3265 else if ((!strcmp(argv[i], "-timing")) ||
3266 (!strcmp(argv[i], "--timing")))
3267 timing++;
3268 else if ((!strcmp(argv[i], "-auto")) ||
3269 (!strcmp(argv[i], "--auto")))
3270 generate++;
3271 else if ((!strcmp(argv[i], "-repeat")) ||
3272 (!strcmp(argv[i], "--repeat"))) {
3273 if (repeat)
3274 repeat *= 10;
3275 else
3276 repeat = 100;
3277 }
3278#ifdef LIBXML_PUSH_ENABLED
3279 else if ((!strcmp(argv[i], "-push")) ||
3280 (!strcmp(argv[i], "--push")))
3281 push++;
Selim Gurun94442ad2013-12-30 18:23:42 -08003282 else if ((!strcmp(argv[i], "-pushsmall")) ||
3283 (!strcmp(argv[i], "--pushsmall"))) {
3284 push++;
3285 pushsize = 10;
3286 }
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003287#endif /* LIBXML_PUSH_ENABLED */
Selim Gurun94442ad2013-12-30 18:23:42 -08003288#ifdef HAVE_MMAP
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003289 else if ((!strcmp(argv[i], "-memory")) ||
3290 (!strcmp(argv[i], "--memory")))
3291 memory++;
3292#endif
3293 else if ((!strcmp(argv[i], "-testIO")) ||
3294 (!strcmp(argv[i], "--testIO")))
3295 testIO++;
3296#ifdef LIBXML_XINCLUDE_ENABLED
3297 else if ((!strcmp(argv[i], "-xinclude")) ||
3298 (!strcmp(argv[i], "--xinclude"))) {
3299 xinclude++;
3300 options |= XML_PARSE_XINCLUDE;
3301 }
3302 else if ((!strcmp(argv[i], "-noxincludenode")) ||
3303 (!strcmp(argv[i], "--noxincludenode"))) {
3304 xinclude++;
3305 options |= XML_PARSE_XINCLUDE;
3306 options |= XML_PARSE_NOXINCNODE;
3307 }
Patrick Scott60a4c352009-07-09 09:30:54 -04003308 else if ((!strcmp(argv[i], "-nofixup-base-uris")) ||
3309 (!strcmp(argv[i], "--nofixup-base-uris"))) {
3310 xinclude++;
3311 options |= XML_PARSE_XINCLUDE;
3312 options |= XML_PARSE_NOBASEFIX;
3313 }
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003314#endif
3315#ifdef LIBXML_OUTPUT_ENABLED
3316#ifdef HAVE_ZLIB_H
3317 else if ((!strcmp(argv[i], "-compress")) ||
3318 (!strcmp(argv[i], "--compress"))) {
3319 compress++;
3320 xmlSetCompressMode(9);
3321 }
3322#endif
3323#endif /* LIBXML_OUTPUT_ENABLED */
3324 else if ((!strcmp(argv[i], "-nowarning")) ||
3325 (!strcmp(argv[i], "--nowarning"))) {
3326 xmlGetWarningsDefaultValue = 0;
3327 xmlPedanticParserDefault(0);
3328 options |= XML_PARSE_NOWARNING;
3329 }
3330 else if ((!strcmp(argv[i], "-pedantic")) ||
3331 (!strcmp(argv[i], "--pedantic"))) {
3332 xmlGetWarningsDefaultValue = 1;
3333 xmlPedanticParserDefault(1);
3334 options |= XML_PARSE_PEDANTIC;
3335 }
3336#ifdef LIBXML_DEBUG_ENABLED
3337 else if ((!strcmp(argv[i], "-debugent")) ||
3338 (!strcmp(argv[i], "--debugent"))) {
3339 debugent++;
3340 xmlParserDebugEntities = 1;
Selim Gurundf143a52012-03-05 14:35:53 -08003341 }
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003342#endif
3343#ifdef LIBXML_C14N_ENABLED
3344 else if ((!strcmp(argv[i], "-c14n")) ||
3345 (!strcmp(argv[i], "--c14n"))) {
3346 canonical++;
3347 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
Selim Gurundf143a52012-03-05 14:35:53 -08003348 }
3349 else if ((!strcmp(argv[i], "-c14n11")) ||
3350 (!strcmp(argv[i], "--c14n11"))) {
3351 canonical_11++;
3352 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
3353 }
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003354 else if ((!strcmp(argv[i], "-exc-c14n")) ||
3355 (!strcmp(argv[i], "--exc-c14n"))) {
3356 exc_canonical++;
3357 options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
Selim Gurundf143a52012-03-05 14:35:53 -08003358 }
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003359#endif
3360#ifdef LIBXML_CATALOG_ENABLED
3361 else if ((!strcmp(argv[i], "-catalogs")) ||
3362 (!strcmp(argv[i], "--catalogs"))) {
3363 catalogs++;
3364 } else if ((!strcmp(argv[i], "-nocatalogs")) ||
3365 (!strcmp(argv[i], "--nocatalogs"))) {
3366 nocatalogs++;
Selim Gurundf143a52012-03-05 14:35:53 -08003367 }
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003368#endif
3369 else if ((!strcmp(argv[i], "-encode")) ||
3370 (!strcmp(argv[i], "--encode"))) {
3371 i++;
3372 encoding = argv[i];
3373 /*
3374 * OK it's for testing purposes
3375 */
3376 xmlAddEncodingAlias("UTF-8", "DVEnc");
3377 }
3378 else if ((!strcmp(argv[i], "-noblanks")) ||
3379 (!strcmp(argv[i], "--noblanks"))) {
Selim Gurun94442ad2013-12-30 18:23:42 -08003380 noblanks++;
3381 xmlKeepBlanksDefault(0);
3382 options |= XML_PARSE_NOBLANKS;
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003383 }
3384 else if ((!strcmp(argv[i], "-maxmem")) ||
3385 (!strcmp(argv[i], "--maxmem"))) {
3386 i++;
3387 if (sscanf(argv[i], "%d", &maxmem) == 1) {
3388 xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc,
3389 myStrdupFunc);
3390 } else {
3391 maxmem = 0;
3392 }
3393 }
3394 else if ((!strcmp(argv[i], "-format")) ||
3395 (!strcmp(argv[i], "--format"))) {
3396 noblanks++;
3397#ifdef LIBXML_OUTPUT_ENABLED
Selim Gurundf143a52012-03-05 14:35:53 -08003398 format = 1;
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003399#endif /* LIBXML_OUTPUT_ENABLED */
3400 xmlKeepBlanksDefault(0);
3401 }
Selim Gurundf143a52012-03-05 14:35:53 -08003402 else if ((!strcmp(argv[i], "-pretty")) ||
3403 (!strcmp(argv[i], "--pretty"))) {
3404 i++;
3405#ifdef LIBXML_OUTPUT_ENABLED
Xin Lie742c3a2017-03-02 10:59:49 -08003406 if (argv[i] != NULL) {
3407 format = atoi(argv[i]);
3408 if (format == 1) {
3409 noblanks++;
3410 xmlKeepBlanksDefault(0);
3411 }
3412 }
Selim Gurun94442ad2013-12-30 18:23:42 -08003413#endif /* LIBXML_OUTPUT_ENABLED */
Selim Gurundf143a52012-03-05 14:35:53 -08003414 }
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003415#ifdef LIBXML_READER_ENABLED
3416 else if ((!strcmp(argv[i], "-stream")) ||
3417 (!strcmp(argv[i], "--stream"))) {
3418 stream++;
3419 }
3420 else if ((!strcmp(argv[i], "-walker")) ||
3421 (!strcmp(argv[i], "--walker"))) {
3422 walker++;
3423 noout++;
3424 }
3425#endif /* LIBXML_READER_ENABLED */
3426#ifdef LIBXML_SAX1_ENABLED
3427 else if ((!strcmp(argv[i], "-sax1")) ||
3428 (!strcmp(argv[i], "--sax1"))) {
Selim Gurundf143a52012-03-05 14:35:53 -08003429 sax1++;
3430 options |= XML_PARSE_SAX1;
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003431 }
3432#endif /* LIBXML_SAX1_ENABLED */
3433 else if ((!strcmp(argv[i], "-sax")) ||
3434 (!strcmp(argv[i], "--sax"))) {
Selim Gurundf143a52012-03-05 14:35:53 -08003435 sax++;
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003436 }
3437 else if ((!strcmp(argv[i], "-chkregister")) ||
3438 (!strcmp(argv[i], "--chkregister"))) {
Selim Gurundf143a52012-03-05 14:35:53 -08003439 chkregister++;
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003440#ifdef LIBXML_SCHEMAS_ENABLED
3441 } else if ((!strcmp(argv[i], "-relaxng")) ||
3442 (!strcmp(argv[i], "--relaxng"))) {
3443 i++;
3444 relaxng = argv[i];
3445 noent++;
3446 options |= XML_PARSE_NOENT;
3447 } else if ((!strcmp(argv[i], "-schema")) ||
3448 (!strcmp(argv[i], "--schema"))) {
3449 i++;
3450 schema = argv[i];
3451 noent++;
3452#endif
3453#ifdef LIBXML_SCHEMATRON_ENABLED
3454 } else if ((!strcmp(argv[i], "-schematron")) ||
3455 (!strcmp(argv[i], "--schematron"))) {
3456 i++;
3457 schematron = argv[i];
3458 noent++;
3459#endif
3460 } else if ((!strcmp(argv[i], "-nonet")) ||
3461 (!strcmp(argv[i], "--nonet"))) {
3462 options |= XML_PARSE_NONET;
3463 xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
3464 } else if ((!strcmp(argv[i], "-nocompact")) ||
3465 (!strcmp(argv[i], "--nocompact"))) {
3466 options &= ~XML_PARSE_COMPACT;
3467 } else if ((!strcmp(argv[i], "-load-trace")) ||
3468 (!strcmp(argv[i], "--load-trace"))) {
3469 load_trace++;
3470 } else if ((!strcmp(argv[i], "-path")) ||
3471 (!strcmp(argv[i], "--path"))) {
3472 i++;
3473 parsePath(BAD_CAST argv[i]);
3474#ifdef LIBXML_PATTERN_ENABLED
3475 } else if ((!strcmp(argv[i], "-pattern")) ||
3476 (!strcmp(argv[i], "--pattern"))) {
3477 i++;
3478 pattern = argv[i];
3479#endif
Selim Gurundf143a52012-03-05 14:35:53 -08003480#ifdef LIBXML_XPATH_ENABLED
3481 } else if ((!strcmp(argv[i], "-xpath")) ||
3482 (!strcmp(argv[i], "--xpath"))) {
3483 i++;
3484 noout++;
3485 xpathquery = argv[i];
3486#endif
Patrick Scott60a4c352009-07-09 09:30:54 -04003487 } else if ((!strcmp(argv[i], "-oldxml10")) ||
3488 (!strcmp(argv[i], "--oldxml10"))) {
3489 oldxml10++;
3490 options |= XML_PARSE_OLD10;
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003491 } else {
3492 fprintf(stderr, "Unknown option %s\n", argv[i]);
3493 usage(argv[0]);
3494 return(1);
3495 }
3496 }
3497
3498#ifdef LIBXML_CATALOG_ENABLED
3499 if (nocatalogs == 0) {
3500 if (catalogs) {
3501 const char *catal;
3502
3503 catal = getenv("SGML_CATALOG_FILES");
3504 if (catal != NULL) {
3505 xmlLoadCatalogs(catal);
3506 } else {
3507 fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
3508 }
3509 }
3510 }
3511#endif
3512
3513#ifdef LIBXML_SAX1_ENABLED
3514 if (sax1)
3515 xmlSAXDefaultVersion(1);
3516 else
3517 xmlSAXDefaultVersion(2);
3518#endif /* LIBXML_SAX1_ENABLED */
3519
3520 if (chkregister) {
3521 xmlRegisterNodeDefault(registerNode);
3522 xmlDeregisterNodeDefault(deregisterNode);
3523 }
Selim Gurundf143a52012-03-05 14:35:53 -08003524
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003525 indent = getenv("XMLLINT_INDENT");
3526 if(indent != NULL) {
3527 xmlTreeIndentString = indent;
3528 }
Selim Gurundf143a52012-03-05 14:35:53 -08003529
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003530
3531 defaultEntityLoader = xmlGetExternalEntityLoader();
3532 xmlSetExternalEntityLoader(xmllintExternalEntityLoader);
3533
3534 xmlLineNumbersDefault(1);
3535 if (loaddtd != 0)
3536 xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
3537 if (dtdattrs)
3538 xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
3539 if (noent != 0) xmlSubstituteEntitiesDefault(1);
3540#ifdef LIBXML_VALID_ENABLED
3541 if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
3542#endif /* LIBXML_VALID_ENABLED */
3543 if ((htmlout) && (!nowrap)) {
3544 xmlGenericError(xmlGenericErrorContext,
3545 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
3546 xmlGenericError(xmlGenericErrorContext,
3547 "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
3548 xmlGenericError(xmlGenericErrorContext,
3549 "<html><head><title>%s output</title></head>\n",
3550 argv[0]);
Selim Gurundf143a52012-03-05 14:35:53 -08003551 xmlGenericError(xmlGenericErrorContext,
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003552 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
3553 argv[0]);
3554 }
3555
3556#ifdef LIBXML_SCHEMATRON_ENABLED
3557 if ((schematron != NULL) && (sax == 0)
3558#ifdef LIBXML_READER_ENABLED
3559 && (stream == 0)
3560#endif /* LIBXML_READER_ENABLED */
3561 ) {
3562 xmlSchematronParserCtxtPtr ctxt;
3563
3564 /* forces loading the DTDs */
Selim Gurundf143a52012-03-05 14:35:53 -08003565 xmlLoadExtDtdDefaultValue |= 1;
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003566 options |= XML_PARSE_DTDLOAD;
3567 if (timing) {
3568 startTimer();
3569 }
3570 ctxt = xmlSchematronNewParserCtxt(schematron);
3571#if 0
3572 xmlSchematronSetParserErrors(ctxt,
3573 (xmlSchematronValidityErrorFunc) fprintf,
3574 (xmlSchematronValidityWarningFunc) fprintf,
3575 stderr);
3576#endif
3577 wxschematron = xmlSchematronParse(ctxt);
3578 if (wxschematron == NULL) {
3579 xmlGenericError(xmlGenericErrorContext,
3580 "Schematron schema %s failed to compile\n", schematron);
3581 progresult = XMLLINT_ERR_SCHEMACOMP;
3582 schematron = NULL;
3583 }
3584 xmlSchematronFreeParserCtxt(ctxt);
3585 if (timing) {
3586 endTimer("Compiling the schemas");
3587 }
3588 }
3589#endif
3590#ifdef LIBXML_SCHEMAS_ENABLED
3591 if ((relaxng != NULL) && (sax == 0)
3592#ifdef LIBXML_READER_ENABLED
3593 && (stream == 0)
3594#endif /* LIBXML_READER_ENABLED */
3595 ) {
3596 xmlRelaxNGParserCtxtPtr ctxt;
3597
3598 /* forces loading the DTDs */
Selim Gurundf143a52012-03-05 14:35:53 -08003599 xmlLoadExtDtdDefaultValue |= 1;
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003600 options |= XML_PARSE_DTDLOAD;
3601 if (timing) {
3602 startTimer();
3603 }
3604 ctxt = xmlRelaxNGNewParserCtxt(relaxng);
3605 xmlRelaxNGSetParserErrors(ctxt,
3606 (xmlRelaxNGValidityErrorFunc) fprintf,
3607 (xmlRelaxNGValidityWarningFunc) fprintf,
3608 stderr);
3609 relaxngschemas = xmlRelaxNGParse(ctxt);
3610 if (relaxngschemas == NULL) {
3611 xmlGenericError(xmlGenericErrorContext,
3612 "Relax-NG schema %s failed to compile\n", relaxng);
3613 progresult = XMLLINT_ERR_SCHEMACOMP;
3614 relaxng = NULL;
3615 }
3616 xmlRelaxNGFreeParserCtxt(ctxt);
3617 if (timing) {
3618 endTimer("Compiling the schemas");
3619 }
3620 } else if ((schema != NULL)
3621#ifdef LIBXML_READER_ENABLED
3622 && (stream == 0)
3623#endif
3624 ) {
3625 xmlSchemaParserCtxtPtr ctxt;
3626
3627 if (timing) {
3628 startTimer();
3629 }
3630 ctxt = xmlSchemaNewParserCtxt(schema);
3631 xmlSchemaSetParserErrors(ctxt,
3632 (xmlSchemaValidityErrorFunc) fprintf,
3633 (xmlSchemaValidityWarningFunc) fprintf,
3634 stderr);
3635 wxschemas = xmlSchemaParse(ctxt);
3636 if (wxschemas == NULL) {
3637 xmlGenericError(xmlGenericErrorContext,
3638 "WXS schema %s failed to compile\n", schema);
3639 progresult = XMLLINT_ERR_SCHEMACOMP;
3640 schema = NULL;
3641 }
3642 xmlSchemaFreeParserCtxt(ctxt);
3643 if (timing) {
3644 endTimer("Compiling the schemas");
3645 }
3646 }
3647#endif /* LIBXML_SCHEMAS_ENABLED */
3648#ifdef LIBXML_PATTERN_ENABLED
3649 if ((pattern != NULL)
3650#ifdef LIBXML_READER_ENABLED
3651 && (walker == 0)
3652#endif
3653 ) {
3654 patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
3655 if (patternc == NULL) {
3656 xmlGenericError(xmlGenericErrorContext,
3657 "Pattern %s failed to compile\n", pattern);
3658 progresult = XMLLINT_ERR_SCHEMAPAT;
3659 pattern = NULL;
3660 }
3661 }
3662#endif /* LIBXML_PATTERN_ENABLED */
3663 for (i = 1; i < argc ; i++) {
3664 if ((!strcmp(argv[i], "-encode")) ||
3665 (!strcmp(argv[i], "--encode"))) {
3666 i++;
3667 continue;
3668 } else if ((!strcmp(argv[i], "-o")) ||
3669 (!strcmp(argv[i], "-output")) ||
3670 (!strcmp(argv[i], "--output"))) {
3671 i++;
3672 continue;
3673 }
3674#ifdef LIBXML_VALID_ENABLED
3675 if ((!strcmp(argv[i], "-dtdvalid")) ||
3676 (!strcmp(argv[i], "--dtdvalid"))) {
3677 i++;
3678 continue;
Selim Gurundf143a52012-03-05 14:35:53 -08003679 }
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003680 if ((!strcmp(argv[i], "-path")) ||
3681 (!strcmp(argv[i], "--path"))) {
3682 i++;
3683 continue;
3684 }
3685 if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
3686 (!strcmp(argv[i], "--dtdvalidfpi"))) {
3687 i++;
3688 continue;
3689 }
3690#endif /* LIBXML_VALID_ENABLED */
3691 if ((!strcmp(argv[i], "-relaxng")) ||
3692 (!strcmp(argv[i], "--relaxng"))) {
3693 i++;
3694 continue;
3695 }
3696 if ((!strcmp(argv[i], "-maxmem")) ||
3697 (!strcmp(argv[i], "--maxmem"))) {
3698 i++;
3699 continue;
3700 }
Selim Gurundf143a52012-03-05 14:35:53 -08003701 if ((!strcmp(argv[i], "-pretty")) ||
3702 (!strcmp(argv[i], "--pretty"))) {
3703 i++;
3704 continue;
3705 }
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003706 if ((!strcmp(argv[i], "-schema")) ||
3707 (!strcmp(argv[i], "--schema"))) {
3708 i++;
3709 continue;
3710 }
3711 if ((!strcmp(argv[i], "-schematron")) ||
3712 (!strcmp(argv[i], "--schematron"))) {
3713 i++;
3714 continue;
3715 }
3716#ifdef LIBXML_PATTERN_ENABLED
3717 if ((!strcmp(argv[i], "-pattern")) ||
3718 (!strcmp(argv[i], "--pattern"))) {
3719 i++;
3720 continue;
3721 }
3722#endif
Selim Gurundf143a52012-03-05 14:35:53 -08003723#ifdef LIBXML_XPATH_ENABLED
3724 if ((!strcmp(argv[i], "-xpath")) ||
3725 (!strcmp(argv[i], "--xpath"))) {
3726 i++;
3727 continue;
3728 }
3729#endif
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003730 if ((timing) && (repeat))
3731 startTimer();
3732 /* Remember file names. "-" means stdin. <sven@zen.org> */
3733 if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
3734 if (repeat) {
3735 xmlParserCtxtPtr ctxt = NULL;
3736
3737 for (acount = 0;acount < repeat;acount++) {
3738#ifdef LIBXML_READER_ENABLED
3739 if (stream != 0) {
3740 streamFile(argv[i]);
3741 } else {
3742#endif /* LIBXML_READER_ENABLED */
3743 if (sax) {
3744 testSAX(argv[i]);
3745 } else {
3746 if (ctxt == NULL)
3747 ctxt = xmlNewParserCtxt();
3748 parseAndPrintFile(argv[i], ctxt);
3749 }
3750#ifdef LIBXML_READER_ENABLED
3751 }
3752#endif /* LIBXML_READER_ENABLED */
3753 }
3754 if (ctxt != NULL)
3755 xmlFreeParserCtxt(ctxt);
3756 } else {
3757 nbregister = 0;
3758
3759#ifdef LIBXML_READER_ENABLED
3760 if (stream != 0)
3761 streamFile(argv[i]);
3762 else
3763#endif /* LIBXML_READER_ENABLED */
3764 if (sax) {
3765 testSAX(argv[i]);
3766 } else {
3767 parseAndPrintFile(argv[i], NULL);
3768 }
3769
3770 if ((chkregister) && (nbregister != 0)) {
3771 fprintf(stderr, "Registration count off: %d\n", nbregister);
3772 progresult = XMLLINT_ERR_RDREGIS;
3773 }
3774 }
3775 files ++;
3776 if ((timing) && (repeat)) {
3777 endTimer("%d iterations", repeat);
3778 }
3779 }
3780 }
Selim Gurundf143a52012-03-05 14:35:53 -08003781 if (generate)
The Android Open Source Projectab4e2e92009-03-03 19:30:06 -08003782 parseAndPrintFile(NULL, NULL);
3783 if ((htmlout) && (!nowrap)) {
3784 xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
3785 }
3786 if ((files == 0) && (!generate) && (version == 0)) {
3787 usage(argv[0]);
3788 }
3789#ifdef LIBXML_SCHEMATRON_ENABLED
3790 if (wxschematron != NULL)
3791 xmlSchematronFree(wxschematron);
3792#endif
3793#ifdef LIBXML_SCHEMAS_ENABLED
3794 if (relaxngschemas != NULL)
3795 xmlRelaxNGFree(relaxngschemas);
3796 if (wxschemas != NULL)
3797 xmlSchemaFree(wxschemas);
3798 xmlRelaxNGCleanupTypes();
3799#endif
3800#ifdef LIBXML_PATTERN_ENABLED
3801 if (patternc != NULL)
3802 xmlFreePattern(patternc);
3803#endif
3804 xmlCleanupParser();
3805 xmlMemoryDump();
3806
3807 return(progresult);
3808}
3809