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