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