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