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