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