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 	    return;
   1842 
   1843 	reader = xmlReaderForMemory(base, info.st_size, filename,
   1844 	                            NULL, options);
   1845     } else
   1846 #endif
   1847 	reader = xmlReaderForFile(filename, NULL, options);
   1848 #ifdef LIBXML_PATTERN_ENABLED
   1849     if (pattern != NULL) {
   1850         patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
   1851 	if (patternc == NULL) {
   1852 	    xmlGenericError(xmlGenericErrorContext,
   1853 		    "Pattern %s failed to compile\n", pattern);
   1854             progresult = XMLLINT_ERR_SCHEMAPAT;
   1855 	    pattern = NULL;
   1856 	}
   1857     }
   1858     if (patternc != NULL) {
   1859         patstream = xmlPatternGetStreamCtxt(patternc);
   1860 	if (patstream != NULL) {
   1861 	    ret = xmlStreamPush(patstream, NULL, NULL);
   1862 	    if (ret < 0) {
   1863 		fprintf(stderr, "xmlStreamPush() failure\n");
   1864 		xmlFreeStreamCtxt(patstream);
   1865 		patstream = NULL;
   1866             }
   1867 	}
   1868     }
   1869 #endif
   1870 
   1871 
   1872     if (reader != NULL) {
   1873 #ifdef LIBXML_VALID_ENABLED
   1874 	if (valid)
   1875 	    xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
   1876 	else
   1877 #endif /* LIBXML_VALID_ENABLED */
   1878 	    if (loaddtd)
   1879 		xmlTextReaderSetParserProp(reader, XML_PARSER_LOADDTD, 1);
   1880 #ifdef LIBXML_SCHEMAS_ENABLED
   1881 	if (relaxng != NULL) {
   1882 	    if ((timing) && (!repeat)) {
   1883 		startTimer();
   1884 	    }
   1885 	    ret = xmlTextReaderRelaxNGValidate(reader, relaxng);
   1886 	    if (ret < 0) {
   1887 		xmlGenericError(xmlGenericErrorContext,
   1888 			"Relax-NG schema %s failed to compile\n", relaxng);
   1889 		progresult = XMLLINT_ERR_SCHEMACOMP;
   1890 		relaxng = NULL;
   1891 	    }
   1892 	    if ((timing) && (!repeat)) {
   1893 		endTimer("Compiling the schemas");
   1894 	    }
   1895 	}
   1896 	if (schema != NULL) {
   1897 	    if ((timing) && (!repeat)) {
   1898 		startTimer();
   1899 	    }
   1900 	    ret = xmlTextReaderSchemaValidate(reader, schema);
   1901 	    if (ret < 0) {
   1902 		xmlGenericError(xmlGenericErrorContext,
   1903 			"XSD schema %s failed to compile\n", schema);
   1904 		progresult = XMLLINT_ERR_SCHEMACOMP;
   1905 		schema = NULL;
   1906 	    }
   1907 	    if ((timing) && (!repeat)) {
   1908 		endTimer("Compiling the schemas");
   1909 	    }
   1910 	}
   1911 #endif
   1912 
   1913 	/*
   1914 	 * Process all nodes in sequence
   1915 	 */
   1916 	if ((timing) && (!repeat)) {
   1917 	    startTimer();
   1918 	}
   1919 	ret = xmlTextReaderRead(reader);
   1920 	while (ret == 1) {
   1921 	    if ((debug)
   1922 #ifdef LIBXML_PATTERN_ENABLED
   1923 	        || (patternc)
   1924 #endif
   1925 	       )
   1926 		processNode(reader);
   1927 	    ret = xmlTextReaderRead(reader);
   1928 	}
   1929 	if ((timing) && (!repeat)) {
   1930 #ifdef LIBXML_SCHEMAS_ENABLED
   1931 	    if (relaxng != NULL)
   1932 		endTimer("Parsing and validating");
   1933 	    else
   1934 #endif
   1935 #ifdef LIBXML_VALID_ENABLED
   1936 	    if (valid)
   1937 		endTimer("Parsing and validating");
   1938 	    else
   1939 #endif
   1940 	    endTimer("Parsing");
   1941 	}
   1942 
   1943 #ifdef LIBXML_VALID_ENABLED
   1944 	if (valid) {
   1945 	    if (xmlTextReaderIsValid(reader) != 1) {
   1946 		xmlGenericError(xmlGenericErrorContext,
   1947 			"Document %s does not validate\n", filename);
   1948 		progresult = XMLLINT_ERR_VALID;
   1949 	    }
   1950 	}
   1951 #endif /* LIBXML_VALID_ENABLED */
   1952 #ifdef LIBXML_SCHEMAS_ENABLED
   1953 	if ((relaxng != NULL) || (schema != NULL)) {
   1954 	    if (xmlTextReaderIsValid(reader) != 1) {
   1955 		fprintf(stderr, "%s fails to validate\n", filename);
   1956 		progresult = XMLLINT_ERR_VALID;
   1957 	    } else {
   1958 		fprintf(stderr, "%s validates\n", filename);
   1959 	    }
   1960 	}
   1961 #endif
   1962 	/*
   1963 	 * Done, cleanup and status
   1964 	 */
   1965 	xmlFreeTextReader(reader);
   1966 	if (ret != 0) {
   1967 	    fprintf(stderr, "%s : failed to parse\n", filename);
   1968 	    progresult = XMLLINT_ERR_UNCLASS;
   1969 	}
   1970     } else {
   1971 	fprintf(stderr, "Unable to open %s\n", filename);
   1972 	progresult = XMLLINT_ERR_UNCLASS;
   1973     }
   1974 #ifdef LIBXML_PATTERN_ENABLED
   1975     if (patstream != NULL) {
   1976 	xmlFreeStreamCtxt(patstream);
   1977 	patstream = NULL;
   1978     }
   1979 #endif
   1980 #ifdef HAVE_MMAP
   1981     if (memory) {
   1982         xmlFreeParserInputBuffer(input);
   1983 	munmap((char *) base, info.st_size);
   1984 	close(fd);
   1985     }
   1986 #endif
   1987 }
   1988 
   1989 static void walkDoc(xmlDocPtr doc) {
   1990     xmlTextReaderPtr reader;
   1991     int ret;
   1992 
   1993 #ifdef LIBXML_PATTERN_ENABLED
   1994     xmlNodePtr root;
   1995     const xmlChar *namespaces[22];
   1996     int i;
   1997     xmlNsPtr ns;
   1998 
   1999     root = xmlDocGetRootElement(doc);
   2000     for (ns = root->nsDef, i = 0;ns != NULL && i < 20;ns=ns->next) {
   2001         namespaces[i++] = ns->href;
   2002         namespaces[i++] = ns->prefix;
   2003     }
   2004     namespaces[i++] = NULL;
   2005     namespaces[i] = NULL;
   2006 
   2007     if (pattern != NULL) {
   2008         patternc = xmlPatterncompile((const xmlChar *) pattern, doc->dict,
   2009 	                             0, &namespaces[0]);
   2010 	if (patternc == NULL) {
   2011 	    xmlGenericError(xmlGenericErrorContext,
   2012 		    "Pattern %s failed to compile\n", pattern);
   2013             progresult = XMLLINT_ERR_SCHEMAPAT;
   2014 	    pattern = NULL;
   2015 	}
   2016     }
   2017     if (patternc != NULL) {
   2018         patstream = xmlPatternGetStreamCtxt(patternc);
   2019 	if (patstream != NULL) {
   2020 	    ret = xmlStreamPush(patstream, NULL, NULL);
   2021 	    if (ret < 0) {
   2022 		fprintf(stderr, "xmlStreamPush() failure\n");
   2023 		xmlFreeStreamCtxt(patstream);
   2024 		patstream = NULL;
   2025             }
   2026 	}
   2027     }
   2028 #endif /* LIBXML_PATTERN_ENABLED */
   2029     reader = xmlReaderWalker(doc);
   2030     if (reader != NULL) {
   2031 	if ((timing) && (!repeat)) {
   2032 	    startTimer();
   2033 	}
   2034 	ret = xmlTextReaderRead(reader);
   2035 	while (ret == 1) {
   2036 	    if ((debug)
   2037 #ifdef LIBXML_PATTERN_ENABLED
   2038 	        || (patternc)
   2039 #endif
   2040 	       )
   2041 		processNode(reader);
   2042 	    ret = xmlTextReaderRead(reader);
   2043 	}
   2044 	if ((timing) && (!repeat)) {
   2045 	    endTimer("walking through the doc");
   2046 	}
   2047 	xmlFreeTextReader(reader);
   2048 	if (ret != 0) {
   2049 	    fprintf(stderr, "failed to walk through the doc\n");
   2050 	    progresult = XMLLINT_ERR_UNCLASS;
   2051 	}
   2052     } else {
   2053 	fprintf(stderr, "Failed to crate a reader from the document\n");
   2054 	progresult = XMLLINT_ERR_UNCLASS;
   2055     }
   2056 #ifdef LIBXML_PATTERN_ENABLED
   2057     if (patstream != NULL) {
   2058 	xmlFreeStreamCtxt(patstream);
   2059 	patstream = NULL;
   2060     }
   2061 #endif
   2062 }
   2063 #endif /* LIBXML_READER_ENABLED */
   2064 
   2065 #ifdef LIBXML_XPATH_ENABLED
   2066 /************************************************************************
   2067  *									*
   2068  *			XPath Query                                     *
   2069  *									*
   2070  ************************************************************************/
   2071 
   2072 static void doXPathDump(xmlXPathObjectPtr cur) {
   2073     switch(cur->type) {
   2074         case XPATH_NODESET: {
   2075             int i;
   2076             xmlNodePtr node;
   2077 #ifdef LIBXML_OUTPUT_ENABLED
   2078             xmlSaveCtxtPtr ctxt;
   2079 
   2080             if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr <= 0)) {
   2081                 fprintf(stderr, "XPath set is empty\n");
   2082                 progresult = XMLLINT_ERR_XPATH;
   2083                 break;
   2084             }
   2085             ctxt = xmlSaveToFd(1, NULL, 0);
   2086             if (ctxt == NULL) {
   2087                 fprintf(stderr, "Out of memory for XPath\n");
   2088                 progresult = XMLLINT_ERR_MEM;
   2089                 return;
   2090             }
   2091             for (i = 0;i < cur->nodesetval->nodeNr;i++) {
   2092                 node = cur->nodesetval->nodeTab[i];
   2093                 xmlSaveTree(ctxt, node);
   2094             }
   2095             xmlSaveClose(ctxt);
   2096 #else
   2097             printf("xpath returned %d nodes\n", cur->nodesetval->nodeNr);
   2098 #endif
   2099 	    break;
   2100         }
   2101         case XPATH_BOOLEAN:
   2102 	    if (cur->boolval) printf("true");
   2103 	    else printf("false");
   2104 	    break;
   2105         case XPATH_NUMBER:
   2106 	    switch (xmlXPathIsInf(cur->floatval)) {
   2107 	    case 1:
   2108 		printf("Infinity");
   2109 		break;
   2110 	    case -1:
   2111 		printf("-Infinity");
   2112 		break;
   2113 	    default:
   2114 		if (xmlXPathIsNaN(cur->floatval)) {
   2115 		    printf("NaN");
   2116 		} else {
   2117 		    printf("%0g", cur->floatval);
   2118 		}
   2119 	    }
   2120 	    break;
   2121         case XPATH_STRING:
   2122 	    printf("%s", (const char *) cur->stringval);
   2123 	    break;
   2124         case XPATH_UNDEFINED:
   2125 	    fprintf(stderr, "XPath Object is uninitialized\n");
   2126             progresult = XMLLINT_ERR_XPATH;
   2127 	    break;
   2128 	default:
   2129 	    fprintf(stderr, "XPath object of unexpected type\n");
   2130             progresult = XMLLINT_ERR_XPATH;
   2131 	    break;
   2132     }
   2133 }
   2134 
   2135 static void doXPathQuery(xmlDocPtr doc, const char *query) {
   2136     xmlXPathContextPtr ctxt;
   2137     xmlXPathObjectPtr res;
   2138 
   2139     ctxt = xmlXPathNewContext(doc);
   2140     if (ctxt == NULL) {
   2141         fprintf(stderr, "Out of memory for XPath\n");
   2142         progresult = XMLLINT_ERR_MEM;
   2143         return;
   2144     }
   2145     ctxt->node = (xmlNodePtr) doc;
   2146     res = xmlXPathEval(BAD_CAST query, ctxt);
   2147     xmlXPathFreeContext(ctxt);
   2148 
   2149     if (res == NULL) {
   2150         fprintf(stderr, "XPath evaluation failure\n");
   2151         progresult = XMLLINT_ERR_XPATH;
   2152         return;
   2153     }
   2154     doXPathDump(res);
   2155     xmlXPathFreeObject(res);
   2156 }
   2157 #endif /* LIBXML_XPATH_ENABLED */
   2158 
   2159 /************************************************************************
   2160  *									*
   2161  *			Tree Test processing				*
   2162  *									*
   2163  ************************************************************************/
   2164 static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
   2165     xmlDocPtr doc = NULL;
   2166 #ifdef LIBXML_TREE_ENABLED
   2167     xmlDocPtr tmp;
   2168 #endif /* LIBXML_TREE_ENABLED */
   2169 
   2170     if ((timing) && (!repeat))
   2171 	startTimer();
   2172 
   2173 
   2174 #ifdef LIBXML_TREE_ENABLED
   2175     if (filename == NULL) {
   2176 	if (generate) {
   2177 	    xmlNodePtr n;
   2178 
   2179 	    doc = xmlNewDoc(BAD_CAST "1.0");
   2180 	    n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL);
   2181 	    xmlNodeSetContent(n, BAD_CAST "abc");
   2182 	    xmlDocSetRootElement(doc, n);
   2183 	}
   2184     }
   2185 #endif /* LIBXML_TREE_ENABLED */
   2186 #ifdef LIBXML_HTML_ENABLED
   2187 #ifdef LIBXML_PUSH_ENABLED
   2188     else if ((html) && (push)) {
   2189         FILE *f;
   2190 
   2191 #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
   2192 	f = fopen(filename, "rb");
   2193 #else
   2194 	f = fopen(filename, "r");
   2195 #endif
   2196         if (f != NULL) {
   2197             int res;
   2198             char chars[4096];
   2199             htmlParserCtxtPtr ctxt;
   2200 
   2201             res = fread(chars, 1, 4, f);
   2202             if (res > 0) {
   2203                 ctxt = htmlCreatePushParserCtxt(NULL, NULL,
   2204                             chars, res, filename, XML_CHAR_ENCODING_NONE);
   2205                 while ((res = fread(chars, 1, pushsize, f)) > 0) {
   2206                     htmlParseChunk(ctxt, chars, res, 0);
   2207                 }
   2208                 htmlParseChunk(ctxt, chars, 0, 1);
   2209                 doc = ctxt->myDoc;
   2210                 htmlFreeParserCtxt(ctxt);
   2211             }
   2212             fclose(f);
   2213         }
   2214     }
   2215 #endif /* LIBXML_PUSH_ENABLED */
   2216 #ifdef HAVE_MMAP
   2217     else if ((html) && (memory)) {
   2218 	int fd;
   2219 	struct stat info;
   2220 	const char *base;
   2221 	if (stat(filename, &info) < 0)
   2222 	    return;
   2223 	if ((fd = open(filename, O_RDONLY)) < 0)
   2224 	    return;
   2225 	base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
   2226 	if (base == (void *) MAP_FAILED)
   2227 	    return;
   2228 
   2229 	doc = htmlReadMemory((char *) base, info.st_size, filename,
   2230 	                     NULL, options);
   2231 
   2232 	munmap((char *) base, info.st_size);
   2233 	close(fd);
   2234     }
   2235 #endif
   2236     else if (html) {
   2237 	doc = htmlReadFile(filename, NULL, options);
   2238     }
   2239 #endif /* LIBXML_HTML_ENABLED */
   2240     else {
   2241 #ifdef LIBXML_PUSH_ENABLED
   2242 	/*
   2243 	 * build an XML tree from a string;
   2244 	 */
   2245 	if (push) {
   2246 	    FILE *f;
   2247 
   2248 	    /* '-' Usually means stdin -<sven (at) zen.org> */
   2249 	    if ((filename[0] == '-') && (filename[1] == 0)) {
   2250 	      f = stdin;
   2251 	    } else {
   2252 #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
   2253 		f = fopen(filename, "rb");
   2254 #else
   2255 		f = fopen(filename, "r");
   2256 #endif
   2257 	    }
   2258 	    if (f != NULL) {
   2259 		int ret;
   2260 	        int res, size = 1024;
   2261 	        char chars[1024];
   2262                 xmlParserCtxtPtr ctxt;
   2263 
   2264 		/* if (repeat) size = 1024; */
   2265 		res = fread(chars, 1, 4, f);
   2266 		if (res > 0) {
   2267 		    ctxt = xmlCreatePushParserCtxt(NULL, NULL,
   2268 		                chars, res, filename);
   2269 		    xmlCtxtUseOptions(ctxt, options);
   2270 		    while ((res = fread(chars, 1, size, f)) > 0) {
   2271 			xmlParseChunk(ctxt, chars, res, 0);
   2272 		    }
   2273 		    xmlParseChunk(ctxt, chars, 0, 1);
   2274 		    doc = ctxt->myDoc;
   2275 		    ret = ctxt->wellFormed;
   2276 		    xmlFreeParserCtxt(ctxt);
   2277 		    if (!ret) {
   2278 			xmlFreeDoc(doc);
   2279 			doc = NULL;
   2280 		    }
   2281 	        }
   2282                 if (f != stdin)
   2283                     fclose(f);
   2284 	    }
   2285 	} else
   2286 #endif /* LIBXML_PUSH_ENABLED */
   2287         if (testIO) {
   2288 	    if ((filename[0] == '-') && (filename[1] == 0)) {
   2289 	        doc = xmlReadFd(0, NULL, NULL, options);
   2290 	    } else {
   2291 	        FILE *f;
   2292 
   2293 #if defined(_WIN32) || defined (__DJGPP__) && !defined (__CYGWIN__)
   2294 		f = fopen(filename, "rb");
   2295 #else
   2296 		f = fopen(filename, "r");
   2297 #endif
   2298 		if (f != NULL) {
   2299 		    if (rectxt == NULL)
   2300 			doc = xmlReadIO((xmlInputReadCallback) myRead,
   2301 					(xmlInputCloseCallback) myClose, f,
   2302 					filename, NULL, options);
   2303 		    else
   2304 			doc = xmlCtxtReadIO(rectxt,
   2305 			                (xmlInputReadCallback) myRead,
   2306 					(xmlInputCloseCallback) myClose, f,
   2307 					filename, NULL, options);
   2308 		} else
   2309 		    doc = NULL;
   2310 	    }
   2311 	} else if (htmlout) {
   2312 	    xmlParserCtxtPtr ctxt;
   2313 
   2314 	    if (rectxt == NULL)
   2315 		ctxt = xmlNewParserCtxt();
   2316 	    else
   2317 	        ctxt = rectxt;
   2318 	    if (ctxt == NULL) {
   2319 	        doc = NULL;
   2320 	    } else {
   2321 	        ctxt->sax->error = xmlHTMLError;
   2322 	        ctxt->sax->warning = xmlHTMLWarning;
   2323 	        ctxt->vctxt.error = xmlHTMLValidityError;
   2324 	        ctxt->vctxt.warning = xmlHTMLValidityWarning;
   2325 
   2326 		doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
   2327 
   2328 		if (rectxt == NULL)
   2329 		    xmlFreeParserCtxt(ctxt);
   2330 	    }
   2331 #ifdef HAVE_MMAP
   2332 	} else if (memory) {
   2333 	    int fd;
   2334 	    struct stat info;
   2335 	    const char *base;
   2336 	    if (stat(filename, &info) < 0)
   2337 		return;
   2338 	    if ((fd = open(filename, O_RDONLY)) < 0)
   2339 		return;
   2340 	    base = mmap(NULL, info.st_size, PROT_READ, MAP_SHARED, fd, 0) ;
   2341 	    if (base == (void *) MAP_FAILED)
   2342 	        return;
   2343 
   2344 	    if (rectxt == NULL)
   2345 		doc = xmlReadMemory((char *) base, info.st_size,
   2346 		                    filename, NULL, options);
   2347 	    else
   2348 		doc = xmlCtxtReadMemory(rectxt, (char *) base, info.st_size,
   2349 			                filename, NULL, options);
   2350 
   2351 	    munmap((char *) base, info.st_size);
   2352 	    close(fd);
   2353 #endif
   2354 #ifdef LIBXML_VALID_ENABLED
   2355 	} else if (valid) {
   2356 	    xmlParserCtxtPtr ctxt = NULL;
   2357 
   2358 	    if (rectxt == NULL)
   2359 		ctxt = xmlNewParserCtxt();
   2360 	    else
   2361 	        ctxt = rectxt;
   2362 	    if (ctxt == NULL) {
   2363 	        doc = NULL;
   2364 	    } else {
   2365 		doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
   2366 
   2367 		if (ctxt->valid == 0)
   2368 		    progresult = XMLLINT_ERR_RDFILE;
   2369 		if (rectxt == NULL)
   2370 		    xmlFreeParserCtxt(ctxt);
   2371 	    }
   2372 #endif /* LIBXML_VALID_ENABLED */
   2373 	} else {
   2374 	    if (rectxt != NULL)
   2375 	        doc = xmlCtxtReadFile(rectxt, filename, NULL, options);
   2376 	    else {
   2377 #ifdef LIBXML_SAX1_ENABLED
   2378                 if (sax1)
   2379 		    doc = xmlParseFile(filename);
   2380 		else
   2381 #endif /* LIBXML_SAX1_ENABLED */
   2382 		doc = xmlReadFile(filename, NULL, options);
   2383 	    }
   2384 	}
   2385     }
   2386 
   2387     /*
   2388      * If we don't have a document we might as well give up.  Do we
   2389      * want an error message here?  <sven (at) zen.org> */
   2390     if (doc == NULL) {
   2391 	progresult = XMLLINT_ERR_UNCLASS;
   2392 	return;
   2393     }
   2394 
   2395     if ((timing) && (!repeat)) {
   2396 	endTimer("Parsing");
   2397     }
   2398 
   2399     /*
   2400      * Remove DOCTYPE nodes
   2401      */
   2402     if (dropdtd) {
   2403 	xmlDtdPtr dtd;
   2404 
   2405 	dtd = xmlGetIntSubset(doc);
   2406 	if (dtd != NULL) {
   2407 	    xmlUnlinkNode((xmlNodePtr)dtd);
   2408 	    xmlFreeDtd(dtd);
   2409 	}
   2410     }
   2411 
   2412 #ifdef LIBXML_XINCLUDE_ENABLED
   2413     if (xinclude) {
   2414 	if ((timing) && (!repeat)) {
   2415 	    startTimer();
   2416 	}
   2417 	if (xmlXIncludeProcessFlags(doc, options) < 0)
   2418 	    progresult = XMLLINT_ERR_UNCLASS;
   2419 	if ((timing) && (!repeat)) {
   2420 	    endTimer("Xinclude processing");
   2421 	}
   2422     }
   2423 #endif
   2424 
   2425 #ifdef LIBXML_XPATH_ENABLED
   2426     if (xpathquery != NULL) {
   2427         doXPathQuery(doc, xpathquery);
   2428     }
   2429 #endif
   2430 
   2431 #ifdef LIBXML_DEBUG_ENABLED
   2432 #ifdef LIBXML_XPATH_ENABLED
   2433     /*
   2434      * shell interaction
   2435      */
   2436     if (shell) {
   2437         xmlXPathOrderDocElems(doc);
   2438         xmlShell(doc, filename, xmlShellReadline, stdout);
   2439     }
   2440 #endif
   2441 #endif
   2442 
   2443 #ifdef LIBXML_TREE_ENABLED
   2444     /*
   2445      * test intermediate copy if needed.
   2446      */
   2447     if (copy) {
   2448         tmp = doc;
   2449 	if (timing) {
   2450 	    startTimer();
   2451 	}
   2452 	doc = xmlCopyDoc(doc, 1);
   2453 	if (timing) {
   2454 	    endTimer("Copying");
   2455 	}
   2456 	if (timing) {
   2457 	    startTimer();
   2458 	}
   2459 	xmlFreeDoc(tmp);
   2460 	if (timing) {
   2461 	    endTimer("Freeing original");
   2462 	}
   2463     }
   2464 #endif /* LIBXML_TREE_ENABLED */
   2465 
   2466 #ifdef LIBXML_VALID_ENABLED
   2467     if ((insert) && (!html)) {
   2468         const xmlChar* list[256];
   2469 	int nb, i;
   2470 	xmlNodePtr node;
   2471 
   2472 	if (doc->children != NULL) {
   2473 	    node = doc->children;
   2474 	    while ((node != NULL) && (node->last == NULL)) node = node->next;
   2475 	    if (node != NULL) {
   2476 		nb = xmlValidGetValidElements(node->last, NULL, list, 256);
   2477 		if (nb < 0) {
   2478 		    fprintf(stderr, "could not get valid list of elements\n");
   2479 		} else if (nb == 0) {
   2480 		    fprintf(stderr, "No element can be inserted under root\n");
   2481 		} else {
   2482 		    fprintf(stderr, "%d element types can be inserted under root:\n",
   2483 		           nb);
   2484 		    for (i = 0;i < nb;i++) {
   2485 			 fprintf(stderr, "%s\n", (char *) list[i]);
   2486 		    }
   2487 		}
   2488 	    }
   2489 	}
   2490     }else
   2491 #endif /* LIBXML_VALID_ENABLED */
   2492 #ifdef LIBXML_READER_ENABLED
   2493     if (walker) {
   2494         walkDoc(doc);
   2495     }
   2496 #endif /* LIBXML_READER_ENABLED */
   2497 #ifdef LIBXML_OUTPUT_ENABLED
   2498     if (noout == 0) {
   2499         int ret;
   2500 
   2501 	/*
   2502 	 * print it.
   2503 	 */
   2504 #ifdef LIBXML_DEBUG_ENABLED
   2505 	if (!debug) {
   2506 #endif
   2507 	    if ((timing) && (!repeat)) {
   2508 		startTimer();
   2509 	    }
   2510 #ifdef LIBXML_HTML_ENABLED
   2511             if ((html) && (!xmlout)) {
   2512 		if (compress) {
   2513 		    htmlSaveFile(output ? output : "-", doc);
   2514 		}
   2515 		else if (encoding != NULL) {
   2516 		    if (format == 1) {
   2517 			htmlSaveFileFormat(output ? output : "-", doc, encoding, 1);
   2518 		    }
   2519 		    else {
   2520 			htmlSaveFileFormat(output ? output : "-", doc, encoding, 0);
   2521 		    }
   2522 		}
   2523 		else if (format == 1) {
   2524 		    htmlSaveFileFormat(output ? output : "-", doc, NULL, 1);
   2525 		}
   2526 		else {
   2527 		    FILE *out;
   2528 		    if (output == NULL)
   2529 			out = stdout;
   2530 		    else {
   2531 			out = fopen(output,"wb");
   2532 		    }
   2533 		    if (out != NULL) {
   2534 			if (htmlDocDump(out, doc) < 0)
   2535 			    progresult = XMLLINT_ERR_OUT;
   2536 
   2537 			if (output != NULL)
   2538 			    fclose(out);
   2539 		    } else {
   2540 			fprintf(stderr, "failed to open %s\n", output);
   2541 			progresult = XMLLINT_ERR_OUT;
   2542 		    }
   2543 		}
   2544 		if ((timing) && (!repeat)) {
   2545 		    endTimer("Saving");
   2546 		}
   2547 	    } else
   2548 #endif
   2549 #ifdef LIBXML_C14N_ENABLED
   2550             if (canonical) {
   2551 	        xmlChar *result = NULL;
   2552 		int size;
   2553 
   2554 		size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_0, NULL, 1, &result);
   2555 		if (size >= 0) {
   2556 		    if (write(1, result, size) == -1) {
   2557 		        fprintf(stderr, "Can't write data\n");
   2558 		    }
   2559 		    xmlFree(result);
   2560 		} else {
   2561 		    fprintf(stderr, "Failed to canonicalize\n");
   2562 		    progresult = XMLLINT_ERR_OUT;
   2563 		}
   2564 	    } else if (canonical) {
   2565 	        xmlChar *result = NULL;
   2566 		int size;
   2567 
   2568 		size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_1_1, NULL, 1, &result);
   2569 		if (size >= 0) {
   2570 		    if (write(1, result, size) == -1) {
   2571 		        fprintf(stderr, "Can't write data\n");
   2572 		    }
   2573 		    xmlFree(result);
   2574 		} else {
   2575 		    fprintf(stderr, "Failed to canonicalize\n");
   2576 		    progresult = XMLLINT_ERR_OUT;
   2577 		}
   2578 	    } else
   2579             if (exc_canonical) {
   2580 	        xmlChar *result = NULL;
   2581 		int size;
   2582 
   2583 		size = xmlC14NDocDumpMemory(doc, NULL, XML_C14N_EXCLUSIVE_1_0, NULL, 1, &result);
   2584 		if (size >= 0) {
   2585 		    if (write(1, result, size) == -1) {
   2586 		        fprintf(stderr, "Can't write data\n");
   2587 		    }
   2588 		    xmlFree(result);
   2589 		} else {
   2590 		    fprintf(stderr, "Failed to canonicalize\n");
   2591 		    progresult = XMLLINT_ERR_OUT;
   2592 		}
   2593 	    } else
   2594 #endif
   2595 #ifdef HAVE_MMAP
   2596 	    if (memory) {
   2597 		xmlChar *result;
   2598 		int len;
   2599 
   2600 		if (encoding != NULL) {
   2601 		    if (format == 1) {
   2602 		        xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
   2603 		    } else {
   2604 			xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
   2605 		    }
   2606 		} else {
   2607 		    if (format == 1)
   2608 			xmlDocDumpFormatMemory(doc, &result, &len, 1);
   2609 		    else
   2610 			xmlDocDumpMemory(doc, &result, &len);
   2611 		}
   2612 		if (result == NULL) {
   2613 		    fprintf(stderr, "Failed to save\n");
   2614 		    progresult = XMLLINT_ERR_OUT;
   2615 		} else {
   2616 		    if (write(1, result, len) == -1) {
   2617 		        fprintf(stderr, "Can't write data\n");
   2618 		    }
   2619 		    xmlFree(result);
   2620 		}
   2621 
   2622 	    } else
   2623 #endif /* HAVE_MMAP */
   2624 	    if (compress) {
   2625 		xmlSaveFile(output ? output : "-", doc);
   2626 	    } else if (oldout) {
   2627 	        if (encoding != NULL) {
   2628 		    if (format == 1) {
   2629 			ret = xmlSaveFormatFileEnc(output ? output : "-", doc,
   2630 						   encoding, 1);
   2631 		    }
   2632 		    else {
   2633 			ret = xmlSaveFileEnc(output ? output : "-", doc,
   2634 			                     encoding);
   2635 		    }
   2636 		    if (ret < 0) {
   2637 			fprintf(stderr, "failed save to %s\n",
   2638 				output ? output : "-");
   2639 			progresult = XMLLINT_ERR_OUT;
   2640 		    }
   2641 		} else if (format == 1) {
   2642 		    ret = xmlSaveFormatFile(output ? output : "-", doc, 1);
   2643 		    if (ret < 0) {
   2644 			fprintf(stderr, "failed save to %s\n",
   2645 				output ? output : "-");
   2646 			progresult = XMLLINT_ERR_OUT;
   2647 		    }
   2648 		} else {
   2649 		    FILE *out;
   2650 		    if (output == NULL)
   2651 			out = stdout;
   2652 		    else {
   2653 			out = fopen(output,"wb");
   2654 		    }
   2655 		    if (out != NULL) {
   2656 			if (xmlDocDump(out, doc) < 0)
   2657 			    progresult = XMLLINT_ERR_OUT;
   2658 
   2659 			if (output != NULL)
   2660 			    fclose(out);
   2661 		    } else {
   2662 			fprintf(stderr, "failed to open %s\n", output);
   2663 			progresult = XMLLINT_ERR_OUT;
   2664 		    }
   2665 		}
   2666 	    } else {
   2667 	        xmlSaveCtxtPtr ctxt;
   2668 		int saveOpts = 0;
   2669 
   2670                 if (format == 1)
   2671 		    saveOpts |= XML_SAVE_FORMAT;
   2672                 else if (format == 2)
   2673                     saveOpts |= XML_SAVE_WSNONSIG;
   2674 
   2675 #if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
   2676                 if (xmlout)
   2677                     saveOpts |= XML_SAVE_AS_XML;
   2678 #endif
   2679 
   2680 		if (output == NULL)
   2681 		    ctxt = xmlSaveToFd(1, encoding, saveOpts);
   2682 		else
   2683 		    ctxt = xmlSaveToFilename(output, encoding, saveOpts);
   2684 
   2685 		if (ctxt != NULL) {
   2686 		    if (xmlSaveDoc(ctxt, doc) < 0) {
   2687 			fprintf(stderr, "failed save to %s\n",
   2688 				output ? output : "-");
   2689 			progresult = XMLLINT_ERR_OUT;
   2690 		    }
   2691 		    xmlSaveClose(ctxt);
   2692 		} else {
   2693 		    progresult = XMLLINT_ERR_OUT;
   2694 		}
   2695 	    }
   2696 	    if ((timing) && (!repeat)) {
   2697 		endTimer("Saving");
   2698 	    }
   2699 #ifdef LIBXML_DEBUG_ENABLED
   2700 	} else {
   2701 	    FILE *out;
   2702 	    if (output == NULL)
   2703 	        out = stdout;
   2704 	    else {
   2705 		out = fopen(output,"wb");
   2706 	    }
   2707 	    if (out != NULL) {
   2708 		xmlDebugDumpDocument(out, doc);
   2709 
   2710 		if (output != NULL)
   2711 		    fclose(out);
   2712 	    } else {
   2713 		fprintf(stderr, "failed to open %s\n", output);
   2714 		progresult = XMLLINT_ERR_OUT;
   2715 	    }
   2716 	}
   2717 #endif
   2718     }
   2719 #endif /* LIBXML_OUTPUT_ENABLED */
   2720 
   2721 #ifdef LIBXML_VALID_ENABLED
   2722     /*
   2723      * A posteriori validation test
   2724      */
   2725     if ((dtdvalid != NULL) || (dtdvalidfpi != NULL)) {
   2726 	xmlDtdPtr dtd;
   2727 
   2728 	if ((timing) && (!repeat)) {
   2729 	    startTimer();
   2730 	}
   2731 	if (dtdvalid != NULL)
   2732 	    dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
   2733 	else
   2734 	    dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL);
   2735 	if ((timing) && (!repeat)) {
   2736 	    endTimer("Parsing DTD");
   2737 	}
   2738 	if (dtd == NULL) {
   2739 	    if (dtdvalid != NULL)
   2740 		xmlGenericError(xmlGenericErrorContext,
   2741 			"Could not parse DTD %s\n", dtdvalid);
   2742 	    else
   2743 		xmlGenericError(xmlGenericErrorContext,
   2744 			"Could not parse DTD %s\n", dtdvalidfpi);
   2745 	    progresult = XMLLINT_ERR_DTD;
   2746 	} else {
   2747 	    xmlValidCtxtPtr cvp;
   2748 
   2749 	    if ((cvp = xmlNewValidCtxt()) == NULL) {
   2750 		xmlGenericError(xmlGenericErrorContext,
   2751 			"Couldn't allocate validation context\n");
   2752 		exit(-1);
   2753 	    }
   2754 	    cvp->userData = (void *) stderr;
   2755 	    cvp->error    = (xmlValidityErrorFunc) fprintf;
   2756 	    cvp->warning  = (xmlValidityWarningFunc) fprintf;
   2757 
   2758 	    if ((timing) && (!repeat)) {
   2759 		startTimer();
   2760 	    }
   2761 	    if (!xmlValidateDtd(cvp, doc, dtd)) {
   2762 		if (dtdvalid != NULL)
   2763 		    xmlGenericError(xmlGenericErrorContext,
   2764 			    "Document %s does not validate against %s\n",
   2765 			    filename, dtdvalid);
   2766 		else
   2767 		    xmlGenericError(xmlGenericErrorContext,
   2768 			    "Document %s does not validate against %s\n",
   2769 			    filename, dtdvalidfpi);
   2770 		progresult = XMLLINT_ERR_VALID;
   2771 	    }
   2772 	    if ((timing) && (!repeat)) {
   2773 		endTimer("Validating against DTD");
   2774 	    }
   2775 	    xmlFreeValidCtxt(cvp);
   2776 	    xmlFreeDtd(dtd);
   2777 	}
   2778     } else if (postvalid) {
   2779 	xmlValidCtxtPtr cvp;
   2780 
   2781 	if ((cvp = xmlNewValidCtxt()) == NULL) {
   2782 	    xmlGenericError(xmlGenericErrorContext,
   2783 		    "Couldn't allocate validation context\n");
   2784 	    exit(-1);
   2785 	}
   2786 
   2787 	if ((timing) && (!repeat)) {
   2788 	    startTimer();
   2789 	}
   2790 	cvp->userData = (void *) stderr;
   2791 	cvp->error    = (xmlValidityErrorFunc) fprintf;
   2792 	cvp->warning  = (xmlValidityWarningFunc) fprintf;
   2793 	if (!xmlValidateDocument(cvp, doc)) {
   2794 	    xmlGenericError(xmlGenericErrorContext,
   2795 		    "Document %s does not validate\n", filename);
   2796 	    progresult = XMLLINT_ERR_VALID;
   2797 	}
   2798 	if ((timing) && (!repeat)) {
   2799 	    endTimer("Validating");
   2800 	}
   2801 	xmlFreeValidCtxt(cvp);
   2802     }
   2803 #endif /* LIBXML_VALID_ENABLED */
   2804 #ifdef LIBXML_SCHEMATRON_ENABLED
   2805     if (wxschematron != NULL) {
   2806 	xmlSchematronValidCtxtPtr ctxt;
   2807 	int ret;
   2808 	int flag;
   2809 
   2810 	if ((timing) && (!repeat)) {
   2811 	    startTimer();
   2812 	}
   2813 
   2814 	if (debug)
   2815 	    flag = XML_SCHEMATRON_OUT_XML;
   2816 	else
   2817 	    flag = XML_SCHEMATRON_OUT_TEXT;
   2818 	if (noout)
   2819 	    flag |= XML_SCHEMATRON_OUT_QUIET;
   2820 	ctxt = xmlSchematronNewValidCtxt(wxschematron, flag);
   2821 #if 0
   2822 	xmlSchematronSetValidErrors(ctxt,
   2823 		(xmlSchematronValidityErrorFunc) fprintf,
   2824 		(xmlSchematronValidityWarningFunc) fprintf,
   2825 		stderr);
   2826 #endif
   2827 	ret = xmlSchematronValidateDoc(ctxt, doc);
   2828 	if (ret == 0) {
   2829 	    fprintf(stderr, "%s validates\n", filename);
   2830 	} else if (ret > 0) {
   2831 	    fprintf(stderr, "%s fails to validate\n", filename);
   2832 	    progresult = XMLLINT_ERR_VALID;
   2833 	} else {
   2834 	    fprintf(stderr, "%s validation generated an internal error\n",
   2835 		   filename);
   2836 	    progresult = XMLLINT_ERR_VALID;
   2837 	}
   2838 	xmlSchematronFreeValidCtxt(ctxt);
   2839 	if ((timing) && (!repeat)) {
   2840 	    endTimer("Validating");
   2841 	}
   2842     }
   2843 #endif
   2844 #ifdef LIBXML_SCHEMAS_ENABLED
   2845     if (relaxngschemas != NULL) {
   2846 	xmlRelaxNGValidCtxtPtr ctxt;
   2847 	int ret;
   2848 
   2849 	if ((timing) && (!repeat)) {
   2850 	    startTimer();
   2851 	}
   2852 
   2853 	ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
   2854 	xmlRelaxNGSetValidErrors(ctxt,
   2855 		(xmlRelaxNGValidityErrorFunc) fprintf,
   2856 		(xmlRelaxNGValidityWarningFunc) fprintf,
   2857 		stderr);
   2858 	ret = xmlRelaxNGValidateDoc(ctxt, doc);
   2859 	if (ret == 0) {
   2860 	    fprintf(stderr, "%s validates\n", filename);
   2861 	} else if (ret > 0) {
   2862 	    fprintf(stderr, "%s fails to validate\n", filename);
   2863 	    progresult = XMLLINT_ERR_VALID;
   2864 	} else {
   2865 	    fprintf(stderr, "%s validation generated an internal error\n",
   2866 		   filename);
   2867 	    progresult = XMLLINT_ERR_VALID;
   2868 	}
   2869 	xmlRelaxNGFreeValidCtxt(ctxt);
   2870 	if ((timing) && (!repeat)) {
   2871 	    endTimer("Validating");
   2872 	}
   2873     } else if (wxschemas != NULL) {
   2874 	xmlSchemaValidCtxtPtr ctxt;
   2875 	int ret;
   2876 
   2877 	if ((timing) && (!repeat)) {
   2878 	    startTimer();
   2879 	}
   2880 
   2881 	ctxt = xmlSchemaNewValidCtxt(wxschemas);
   2882 	xmlSchemaSetValidErrors(ctxt,
   2883 		(xmlSchemaValidityErrorFunc) fprintf,
   2884 		(xmlSchemaValidityWarningFunc) fprintf,
   2885 		stderr);
   2886 	ret = xmlSchemaValidateDoc(ctxt, doc);
   2887 	if (ret == 0) {
   2888 	    fprintf(stderr, "%s validates\n", filename);
   2889 	} else if (ret > 0) {
   2890 	    fprintf(stderr, "%s fails to validate\n", filename);
   2891 	    progresult = XMLLINT_ERR_VALID;
   2892 	} else {
   2893 	    fprintf(stderr, "%s validation generated an internal error\n",
   2894 		   filename);
   2895 	    progresult = XMLLINT_ERR_VALID;
   2896 	}
   2897 	xmlSchemaFreeValidCtxt(ctxt);
   2898 	if ((timing) && (!repeat)) {
   2899 	    endTimer("Validating");
   2900 	}
   2901     }
   2902 #endif
   2903 
   2904 #ifdef LIBXML_DEBUG_ENABLED
   2905 #if defined(LIBXML_HTML_ENABLED) || defined(LIBXML_VALID_ENABLED)
   2906     if ((debugent) && (!html))
   2907 	xmlDebugDumpEntities(stderr, doc);
   2908 #endif
   2909 #endif
   2910 
   2911     /*
   2912      * free it.
   2913      */
   2914     if ((timing) && (!repeat)) {
   2915 	startTimer();
   2916     }
   2917     xmlFreeDoc(doc);
   2918     if ((timing) && (!repeat)) {
   2919 	endTimer("Freeing");
   2920     }
   2921 }
   2922 
   2923 /************************************************************************
   2924  *									*
   2925  *			Usage and Main					*
   2926  *									*
   2927  ************************************************************************/
   2928 
   2929 static void showVersion(const char *name) {
   2930     fprintf(stderr, "%s: using libxml version %s\n", name, xmlParserVersion);
   2931     fprintf(stderr, "   compiled with: ");
   2932     if (xmlHasFeature(XML_WITH_THREAD)) fprintf(stderr, "Threads ");
   2933     if (xmlHasFeature(XML_WITH_TREE)) fprintf(stderr, "Tree ");
   2934     if (xmlHasFeature(XML_WITH_OUTPUT)) fprintf(stderr, "Output ");
   2935     if (xmlHasFeature(XML_WITH_PUSH)) fprintf(stderr, "Push ");
   2936     if (xmlHasFeature(XML_WITH_READER)) fprintf(stderr, "Reader ");
   2937     if (xmlHasFeature(XML_WITH_PATTERN)) fprintf(stderr, "Patterns ");
   2938     if (xmlHasFeature(XML_WITH_WRITER)) fprintf(stderr, "Writer ");
   2939     if (xmlHasFeature(XML_WITH_SAX1)) fprintf(stderr, "SAXv1 ");
   2940     if (xmlHasFeature(XML_WITH_FTP)) fprintf(stderr, "FTP ");
   2941     if (xmlHasFeature(XML_WITH_HTTP)) fprintf(stderr, "HTTP ");
   2942     if (xmlHasFeature(XML_WITH_VALID)) fprintf(stderr, "DTDValid ");
   2943     if (xmlHasFeature(XML_WITH_HTML)) fprintf(stderr, "HTML ");
   2944     if (xmlHasFeature(XML_WITH_LEGACY)) fprintf(stderr, "Legacy ");
   2945     if (xmlHasFeature(XML_WITH_C14N)) fprintf(stderr, "C14N ");
   2946     if (xmlHasFeature(XML_WITH_CATALOG)) fprintf(stderr, "Catalog ");
   2947     if (xmlHasFeature(XML_WITH_XPATH)) fprintf(stderr, "XPath ");
   2948     if (xmlHasFeature(XML_WITH_XPTR)) fprintf(stderr, "XPointer ");
   2949     if (xmlHasFeature(XML_WITH_XINCLUDE)) fprintf(stderr, "XInclude ");
   2950     if (xmlHasFeature(XML_WITH_ICONV)) fprintf(stderr, "Iconv ");
   2951     if (xmlHasFeature(XML_WITH_ISO8859X)) fprintf(stderr, "ISO8859X ");
   2952     if (xmlHasFeature(XML_WITH_UNICODE)) fprintf(stderr, "Unicode ");
   2953     if (xmlHasFeature(XML_WITH_REGEXP)) fprintf(stderr, "Regexps ");
   2954     if (xmlHasFeature(XML_WITH_AUTOMATA)) fprintf(stderr, "Automata ");
   2955     if (xmlHasFeature(XML_WITH_EXPR)) fprintf(stderr, "Expr ");
   2956     if (xmlHasFeature(XML_WITH_SCHEMAS)) fprintf(stderr, "Schemas ");
   2957     if (xmlHasFeature(XML_WITH_SCHEMATRON)) fprintf(stderr, "Schematron ");
   2958     if (xmlHasFeature(XML_WITH_MODULES)) fprintf(stderr, "Modules ");
   2959     if (xmlHasFeature(XML_WITH_DEBUG)) fprintf(stderr, "Debug ");
   2960     if (xmlHasFeature(XML_WITH_DEBUG_MEM)) fprintf(stderr, "MemDebug ");
   2961     if (xmlHasFeature(XML_WITH_DEBUG_RUN)) fprintf(stderr, "RunDebug ");
   2962     if (xmlHasFeature(XML_WITH_ZLIB)) fprintf(stderr, "Zlib ");
   2963     if (xmlHasFeature(XML_WITH_LZMA)) fprintf(stderr, "Lzma ");
   2964     fprintf(stderr, "\n");
   2965 }
   2966 
   2967 static void usage(const char *name) {
   2968     printf("Usage : %s [options] XMLfiles ...\n", name);
   2969 #ifdef LIBXML_OUTPUT_ENABLED
   2970     printf("\tParse the XML files and output the result of the parsing\n");
   2971 #else
   2972     printf("\tParse the XML files\n");
   2973 #endif /* LIBXML_OUTPUT_ENABLED */
   2974     printf("\t--version : display the version of the XML library used\n");
   2975 #ifdef LIBXML_DEBUG_ENABLED
   2976     printf("\t--debug : dump a debug tree of the in-memory document\n");
   2977     printf("\t--shell : run a navigating shell\n");
   2978     printf("\t--debugent : debug the entities defined in the document\n");
   2979 #else
   2980 #ifdef LIBXML_READER_ENABLED
   2981     printf("\t--debug : dump the nodes content when using --stream\n");
   2982 #endif /* LIBXML_READER_ENABLED */
   2983 #endif
   2984 #ifdef LIBXML_TREE_ENABLED
   2985     printf("\t--copy : used to test the internal copy implementation\n");
   2986 #endif /* LIBXML_TREE_ENABLED */
   2987     printf("\t--recover : output what was parsable on broken XML documents\n");
   2988     printf("\t--huge : remove any internal arbitrary parser limits\n");
   2989     printf("\t--noent : substitute entity references by their value\n");
   2990     printf("\t--noenc : ignore any encoding specified inside the document\n");
   2991     printf("\t--noout : don't output the result tree\n");
   2992     printf("\t--path 'paths': provide a set of paths for resources\n");
   2993     printf("\t--load-trace : print trace of all external entites loaded\n");
   2994     printf("\t--nonet : refuse to fetch DTDs or entities over network\n");
   2995     printf("\t--nocompact : do not generate compact text nodes\n");
   2996     printf("\t--htmlout : output results as HTML\n");
   2997     printf("\t--nowrap : do not put HTML doc wrapper\n");
   2998 #ifdef LIBXML_VALID_ENABLED
   2999     printf("\t--valid : validate the document in addition to std well-formed check\n");
   3000     printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
   3001     printf("\t--dtdvalid URL : do a posteriori validation against a given DTD\n");
   3002     printf("\t--dtdvalidfpi FPI : same but name the DTD with a Public Identifier\n");
   3003 #endif /* LIBXML_VALID_ENABLED */
   3004     printf("\t--timing : print some timings\n");
   3005     printf("\t--output file or -o file: save to a given file\n");
   3006     printf("\t--repeat : repeat 100 times, for timing or profiling\n");
   3007     printf("\t--insert : ad-hoc test for valid insertions\n");
   3008 #ifdef LIBXML_OUTPUT_ENABLED
   3009 #ifdef HAVE_ZLIB_H
   3010     printf("\t--compress : turn on gzip compression of output\n");
   3011 #endif
   3012 #endif /* LIBXML_OUTPUT_ENABLED */
   3013 #ifdef LIBXML_HTML_ENABLED
   3014     printf("\t--html : use the HTML parser\n");
   3015     printf("\t--xmlout : force to use the XML serializer when using --html\n");
   3016     printf("\t--nodefdtd : do not default HTML doctype\n");
   3017 #endif
   3018 #ifdef LIBXML_PUSH_ENABLED
   3019     printf("\t--push : use the push mode of the parser\n");
   3020     printf("\t--pushsmall : use the push mode of the parser using tiny increments\n");
   3021 #endif /* LIBXML_PUSH_ENABLED */
   3022 #ifdef HAVE_MMAP
   3023     printf("\t--memory : parse from memory\n");
   3024 #endif
   3025     printf("\t--maxmem nbbytes : limits memory allocation to nbbytes bytes\n");
   3026     printf("\t--nowarning : do not emit warnings from parser/validator\n");
   3027     printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
   3028     printf("\t--nocdata : replace cdata section with text nodes\n");
   3029 #ifdef LIBXML_OUTPUT_ENABLED
   3030     printf("\t--format : reformat/reindent the input\n");
   3031     printf("\t--encode encoding : output in the given encoding\n");
   3032     printf("\t--dropdtd : remove the DOCTYPE of the input docs\n");
   3033     printf("\t--pretty STYLE : pretty-print in a particular style\n");
   3034     printf("\t                 0 Do not pretty print\n");
   3035     printf("\t                 1 Format the XML content, as --format\n");
   3036     printf("\t                 2 Add whitespace inside tags, preserving content\n");
   3037 #endif /* LIBXML_OUTPUT_ENABLED */
   3038     printf("\t--c14n : save in W3C canonical format v1.0 (with comments)\n");
   3039     printf("\t--c14n11 : save in W3C canonical format v1.1 (with comments)\n");
   3040     printf("\t--exc-c14n : save in W3C exclusive canonical format (with comments)\n");
   3041 #ifdef LIBXML_C14N_ENABLED
   3042 #endif /* LIBXML_C14N_ENABLED */
   3043     printf("\t--nsclean : remove redundant namespace declarations\n");
   3044     printf("\t--testIO : test user I/O support\n");
   3045 #ifdef LIBXML_CATALOG_ENABLED
   3046     printf("\t--catalogs : use SGML catalogs from $SGML_CATALOG_FILES\n");
   3047     printf("\t             otherwise XML Catalogs starting from \n");
   3048     printf("\t         %s are activated by default\n", XML_XML_DEFAULT_CATALOG);
   3049     printf("\t--nocatalogs: deactivate all catalogs\n");
   3050 #endif
   3051     printf("\t--auto : generate a small doc on the fly\n");
   3052 #ifdef LIBXML_XINCLUDE_ENABLED
   3053     printf("\t--xinclude : do XInclude processing\n");
   3054     printf("\t--noxincludenode : same but do not generate XInclude nodes\n");
   3055     printf("\t--nofixup-base-uris : do not fixup xml:base uris\n");
   3056 #endif
   3057     printf("\t--loaddtd : fetch external DTD\n");
   3058     printf("\t--dtdattr : loaddtd + populate the tree with inherited attributes \n");
   3059 #ifdef LIBXML_READER_ENABLED
   3060     printf("\t--stream : use the streaming interface to process very large files\n");
   3061     printf("\t--walker : create a reader and walk though the resulting doc\n");
   3062 #endif /* LIBXML_READER_ENABLED */
   3063 #ifdef LIBXML_PATTERN_ENABLED
   3064     printf("\t--pattern pattern_value : test the pattern support\n");
   3065 #endif
   3066     printf("\t--chkregister : verify the node registration code\n");
   3067 #ifdef LIBXML_SCHEMAS_ENABLED
   3068     printf("\t--relaxng schema : do RelaxNG validation against the schema\n");
   3069     printf("\t--schema schema : do validation against the WXS schema\n");
   3070 #endif
   3071 #ifdef LIBXML_SCHEMATRON_ENABLED
   3072     printf("\t--schematron schema : do validation against a schematron\n");
   3073 #endif
   3074 #ifdef LIBXML_SAX1_ENABLED
   3075     printf("\t--sax1: use the old SAX1 interfaces for processing\n");
   3076 #endif
   3077     printf("\t--sax: do not build a tree but work just at the SAX level\n");
   3078     printf("\t--oldxml10: use XML-1.0 parsing rules before the 5th edition\n");
   3079 #ifdef LIBXML_XPATH_ENABLED
   3080     printf("\t--xpath expr: evaluate the XPath expression, imply --noout\n");
   3081 #endif
   3082 
   3083     printf("\nLibxml project home page: http://xmlsoft.org/\n");
   3084     printf("To report bugs or get some help check: http://xmlsoft.org/bugs.html\n");
   3085 }
   3086 
   3087 static void registerNode(xmlNodePtr node)
   3088 {
   3089     node->_private = malloc(sizeof(long));
   3090     *(long*)node->_private = (long) 0x81726354;
   3091     nbregister++;
   3092 }
   3093 
   3094 static void deregisterNode(xmlNodePtr node)
   3095 {
   3096     assert(node->_private != NULL);
   3097     assert(*(long*)node->_private == (long) 0x81726354);
   3098     free(node->_private);
   3099     nbregister--;
   3100 }
   3101 
   3102 int
   3103 main(int argc, char **argv) {
   3104     int i, acount;
   3105     int files = 0;
   3106     int version = 0;
   3107     const char* indent;
   3108 
   3109     if (argc <= 1) {
   3110 	usage(argv[0]);
   3111 	return(1);
   3112     }
   3113     LIBXML_TEST_VERSION
   3114     for (i = 1; i < argc ; i++) {
   3115 	if (!strcmp(argv[i], "-"))
   3116 	    break;
   3117 
   3118 	if (argv[i][0] != '-')
   3119 	    continue;
   3120 	if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
   3121 	    debug++;
   3122 	else
   3123 #ifdef LIBXML_DEBUG_ENABLED
   3124 	if ((!strcmp(argv[i], "-shell")) ||
   3125 	         (!strcmp(argv[i], "--shell"))) {
   3126 	    shell++;
   3127             noout = 1;
   3128         } else
   3129 #endif
   3130 #ifdef LIBXML_TREE_ENABLED
   3131 	if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
   3132 	    copy++;
   3133 	else
   3134 #endif /* LIBXML_TREE_ENABLED */
   3135 	if ((!strcmp(argv[i], "-recover")) ||
   3136 	         (!strcmp(argv[i], "--recover"))) {
   3137 	    recovery++;
   3138 	    options |= XML_PARSE_RECOVER;
   3139 	} else if ((!strcmp(argv[i], "-huge")) ||
   3140 	         (!strcmp(argv[i], "--huge"))) {
   3141 	    options |= XML_PARSE_HUGE;
   3142 	} else if ((!strcmp(argv[i], "-noent")) ||
   3143 	         (!strcmp(argv[i], "--noent"))) {
   3144 	    noent++;
   3145 	    options |= XML_PARSE_NOENT;
   3146 	} else if ((!strcmp(argv[i], "-noenc")) ||
   3147 	         (!strcmp(argv[i], "--noenc"))) {
   3148 	    noenc++;
   3149 	    options |= XML_PARSE_IGNORE_ENC;
   3150 	} else if ((!strcmp(argv[i], "-nsclean")) ||
   3151 	         (!strcmp(argv[i], "--nsclean"))) {
   3152 	    options |= XML_PARSE_NSCLEAN;
   3153 	} else if ((!strcmp(argv[i], "-nocdata")) ||
   3154 	         (!strcmp(argv[i], "--nocdata"))) {
   3155 	    options |= XML_PARSE_NOCDATA;
   3156 	} else if ((!strcmp(argv[i], "-nodict")) ||
   3157 	         (!strcmp(argv[i], "--nodict"))) {
   3158 	    options |= XML_PARSE_NODICT;
   3159 	} else if ((!strcmp(argv[i], "-version")) ||
   3160 	         (!strcmp(argv[i], "--version"))) {
   3161 	    showVersion(argv[0]);
   3162 	    version = 1;
   3163 	} else if ((!strcmp(argv[i], "-noout")) ||
   3164 	         (!strcmp(argv[i], "--noout")))
   3165 	    noout++;
   3166 #ifdef LIBXML_OUTPUT_ENABLED
   3167 	else if ((!strcmp(argv[i], "-o")) ||
   3168 	         (!strcmp(argv[i], "-output")) ||
   3169 	         (!strcmp(argv[i], "--output"))) {
   3170 	    i++;
   3171 	    output = argv[i];
   3172 	}
   3173 #endif /* LIBXML_OUTPUT_ENABLED */
   3174 	else if ((!strcmp(argv[i], "-htmlout")) ||
   3175 	         (!strcmp(argv[i], "--htmlout")))
   3176 	    htmlout++;
   3177 	else if ((!strcmp(argv[i], "-nowrap")) ||
   3178 	         (!strcmp(argv[i], "--nowrap")))
   3179 	    nowrap++;
   3180 #ifdef LIBXML_HTML_ENABLED
   3181 	else if ((!strcmp(argv[i], "-html")) ||
   3182 	         (!strcmp(argv[i], "--html"))) {
   3183 	    html++;
   3184         }
   3185 	else if ((!strcmp(argv[i], "-xmlout")) ||
   3186 	         (!strcmp(argv[i], "--xmlout"))) {
   3187 	    xmlout++;
   3188 	} else if ((!strcmp(argv[i], "-nodefdtd")) ||
   3189 	         (!strcmp(argv[i], "--nodefdtd"))) {
   3190             nodefdtd++;
   3191 	    options |= HTML_PARSE_NODEFDTD;
   3192         }
   3193 #endif /* LIBXML_HTML_ENABLED */
   3194 	else if ((!strcmp(argv[i], "-loaddtd")) ||
   3195 	         (!strcmp(argv[i], "--loaddtd"))) {
   3196 	    loaddtd++;
   3197 	    options |= XML_PARSE_DTDLOAD;
   3198 	} else if ((!strcmp(argv[i], "-dtdattr")) ||
   3199 	         (!strcmp(argv[i], "--dtdattr"))) {
   3200 	    loaddtd++;
   3201 	    dtdattrs++;
   3202 	    options |= XML_PARSE_DTDATTR;
   3203 	}
   3204 #ifdef LIBXML_VALID_ENABLED
   3205 	else if ((!strcmp(argv[i], "-valid")) ||
   3206 	         (!strcmp(argv[i], "--valid"))) {
   3207 	    valid++;
   3208 	    options |= XML_PARSE_DTDVALID;
   3209 	} else if ((!strcmp(argv[i], "-postvalid")) ||
   3210 	         (!strcmp(argv[i], "--postvalid"))) {
   3211 	    postvalid++;
   3212 	    loaddtd++;
   3213 	    options |= XML_PARSE_DTDLOAD;
   3214 	} else if ((!strcmp(argv[i], "-dtdvalid")) ||
   3215 	         (!strcmp(argv[i], "--dtdvalid"))) {
   3216 	    i++;
   3217 	    dtdvalid = argv[i];
   3218 	    loaddtd++;
   3219 	    options |= XML_PARSE_DTDLOAD;
   3220 	} else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
   3221 	         (!strcmp(argv[i], "--dtdvalidfpi"))) {
   3222 	    i++;
   3223 	    dtdvalidfpi = argv[i];
   3224 	    loaddtd++;
   3225 	    options |= XML_PARSE_DTDLOAD;
   3226         }
   3227 #endif /* LIBXML_VALID_ENABLED */
   3228 	else if ((!strcmp(argv[i], "-dropdtd")) ||
   3229 	         (!strcmp(argv[i], "--dropdtd")))
   3230 	    dropdtd++;
   3231 	else if ((!strcmp(argv[i], "-insert")) ||
   3232 	         (!strcmp(argv[i], "--insert")))
   3233 	    insert++;
   3234 	else if ((!strcmp(argv[i], "-timing")) ||
   3235 	         (!strcmp(argv[i], "--timing")))
   3236 	    timing++;
   3237 	else if ((!strcmp(argv[i], "-auto")) ||
   3238 	         (!strcmp(argv[i], "--auto")))
   3239 	    generate++;
   3240 	else if ((!strcmp(argv[i], "-repeat")) ||
   3241 	         (!strcmp(argv[i], "--repeat"))) {
   3242 	    if (repeat)
   3243 	        repeat *= 10;
   3244 	    else
   3245 	        repeat = 100;
   3246 	}
   3247 #ifdef LIBXML_PUSH_ENABLED
   3248 	else if ((!strcmp(argv[i], "-push")) ||
   3249 	         (!strcmp(argv[i], "--push")))
   3250 	    push++;
   3251 	else if ((!strcmp(argv[i], "-pushsmall")) ||
   3252 	         (!strcmp(argv[i], "--pushsmall"))) {
   3253 	    push++;
   3254             pushsize = 10;
   3255         }
   3256 #endif /* LIBXML_PUSH_ENABLED */
   3257 #ifdef HAVE_MMAP
   3258 	else if ((!strcmp(argv[i], "-memory")) ||
   3259 	         (!strcmp(argv[i], "--memory")))
   3260 	    memory++;
   3261 #endif
   3262 	else if ((!strcmp(argv[i], "-testIO")) ||
   3263 	         (!strcmp(argv[i], "--testIO")))
   3264 	    testIO++;
   3265 #ifdef LIBXML_XINCLUDE_ENABLED
   3266 	else if ((!strcmp(argv[i], "-xinclude")) ||
   3267 	         (!strcmp(argv[i], "--xinclude"))) {
   3268 	    xinclude++;
   3269 	    options |= XML_PARSE_XINCLUDE;
   3270 	}
   3271 	else if ((!strcmp(argv[i], "-noxincludenode")) ||
   3272 	         (!strcmp(argv[i], "--noxincludenode"))) {
   3273 	    xinclude++;
   3274 	    options |= XML_PARSE_XINCLUDE;
   3275 	    options |= XML_PARSE_NOXINCNODE;
   3276 	}
   3277 	else if ((!strcmp(argv[i], "-nofixup-base-uris")) ||
   3278 	         (!strcmp(argv[i], "--nofixup-base-uris"))) {
   3279 	    xinclude++;
   3280 	    options |= XML_PARSE_XINCLUDE;
   3281 	    options |= XML_PARSE_NOBASEFIX;
   3282 	}
   3283 #endif
   3284 #ifdef LIBXML_OUTPUT_ENABLED
   3285 #ifdef HAVE_ZLIB_H
   3286 	else if ((!strcmp(argv[i], "-compress")) ||
   3287 	         (!strcmp(argv[i], "--compress"))) {
   3288 	    compress++;
   3289 	    xmlSetCompressMode(9);
   3290         }
   3291 #endif
   3292 #endif /* LIBXML_OUTPUT_ENABLED */
   3293 	else if ((!strcmp(argv[i], "-nowarning")) ||
   3294 	         (!strcmp(argv[i], "--nowarning"))) {
   3295 	    xmlGetWarningsDefaultValue = 0;
   3296 	    xmlPedanticParserDefault(0);
   3297 	    options |= XML_PARSE_NOWARNING;
   3298         }
   3299 	else if ((!strcmp(argv[i], "-pedantic")) ||
   3300 	         (!strcmp(argv[i], "--pedantic"))) {
   3301 	    xmlGetWarningsDefaultValue = 1;
   3302 	    xmlPedanticParserDefault(1);
   3303 	    options |= XML_PARSE_PEDANTIC;
   3304         }
   3305 #ifdef LIBXML_DEBUG_ENABLED
   3306 	else if ((!strcmp(argv[i], "-debugent")) ||
   3307 		 (!strcmp(argv[i], "--debugent"))) {
   3308 	    debugent++;
   3309 	    xmlParserDebugEntities = 1;
   3310 	}
   3311 #endif
   3312 #ifdef LIBXML_C14N_ENABLED
   3313 	else if ((!strcmp(argv[i], "-c14n")) ||
   3314 		 (!strcmp(argv[i], "--c14n"))) {
   3315 	    canonical++;
   3316 	    options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
   3317 	}
   3318 	else if ((!strcmp(argv[i], "-c14n11")) ||
   3319 		 (!strcmp(argv[i], "--c14n11"))) {
   3320 	    canonical_11++;
   3321 	    options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
   3322 	}
   3323 	else if ((!strcmp(argv[i], "-exc-c14n")) ||
   3324 		 (!strcmp(argv[i], "--exc-c14n"))) {
   3325 	    exc_canonical++;
   3326 	    options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
   3327 	}
   3328 #endif
   3329 #ifdef LIBXML_CATALOG_ENABLED
   3330 	else if ((!strcmp(argv[i], "-catalogs")) ||
   3331 		 (!strcmp(argv[i], "--catalogs"))) {
   3332 	    catalogs++;
   3333 	} else if ((!strcmp(argv[i], "-nocatalogs")) ||
   3334 		 (!strcmp(argv[i], "--nocatalogs"))) {
   3335 	    nocatalogs++;
   3336 	}
   3337 #endif
   3338 	else if ((!strcmp(argv[i], "-encode")) ||
   3339 	         (!strcmp(argv[i], "--encode"))) {
   3340 	    i++;
   3341 	    encoding = argv[i];
   3342 	    /*
   3343 	     * OK it's for testing purposes
   3344 	     */
   3345 	    xmlAddEncodingAlias("UTF-8", "DVEnc");
   3346         }
   3347 	else if ((!strcmp(argv[i], "-noblanks")) ||
   3348 	         (!strcmp(argv[i], "--noblanks"))) {
   3349 	    noblanks++;
   3350 	    xmlKeepBlanksDefault(0);
   3351 	    options |= XML_PARSE_NOBLANKS;
   3352         }
   3353 	else if ((!strcmp(argv[i], "-maxmem")) ||
   3354 	         (!strcmp(argv[i], "--maxmem"))) {
   3355 	     i++;
   3356 	     if (sscanf(argv[i], "%d", &maxmem) == 1) {
   3357 	         xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc,
   3358 		             myStrdupFunc);
   3359 	     } else {
   3360 	         maxmem = 0;
   3361 	     }
   3362         }
   3363 	else if ((!strcmp(argv[i], "-format")) ||
   3364 	         (!strcmp(argv[i], "--format"))) {
   3365 	     noblanks++;
   3366 #ifdef LIBXML_OUTPUT_ENABLED
   3367 	     format = 1;
   3368 #endif /* LIBXML_OUTPUT_ENABLED */
   3369 	     xmlKeepBlanksDefault(0);
   3370 	}
   3371 	else if ((!strcmp(argv[i], "-pretty")) ||
   3372 	         (!strcmp(argv[i], "--pretty"))) {
   3373 	     i++;
   3374 #ifdef LIBXML_OUTPUT_ENABLED
   3375 	     format = atoi(argv[i]);
   3376 	     if (format == 1) {
   3377 	         noblanks++;
   3378 	         xmlKeepBlanksDefault(0);
   3379 	     }
   3380 #endif /* LIBXML_OUTPUT_ENABLED */
   3381 	}
   3382 #ifdef LIBXML_READER_ENABLED
   3383 	else if ((!strcmp(argv[i], "-stream")) ||
   3384 	         (!strcmp(argv[i], "--stream"))) {
   3385 	     stream++;
   3386 	}
   3387 	else if ((!strcmp(argv[i], "-walker")) ||
   3388 	         (!strcmp(argv[i], "--walker"))) {
   3389 	     walker++;
   3390              noout++;
   3391 	}
   3392 #endif /* LIBXML_READER_ENABLED */
   3393 #ifdef LIBXML_SAX1_ENABLED
   3394 	else if ((!strcmp(argv[i], "-sax1")) ||
   3395 	         (!strcmp(argv[i], "--sax1"))) {
   3396 	    sax1++;
   3397 	    options |= XML_PARSE_SAX1;
   3398 	}
   3399 #endif /* LIBXML_SAX1_ENABLED */
   3400 	else if ((!strcmp(argv[i], "-sax")) ||
   3401 	         (!strcmp(argv[i], "--sax"))) {
   3402 	    sax++;
   3403 	}
   3404 	else if ((!strcmp(argv[i], "-chkregister")) ||
   3405 	         (!strcmp(argv[i], "--chkregister"))) {
   3406 	    chkregister++;
   3407 #ifdef LIBXML_SCHEMAS_ENABLED
   3408 	} else if ((!strcmp(argv[i], "-relaxng")) ||
   3409 	         (!strcmp(argv[i], "--relaxng"))) {
   3410 	    i++;
   3411 	    relaxng = argv[i];
   3412 	    noent++;
   3413 	    options |= XML_PARSE_NOENT;
   3414 	} else if ((!strcmp(argv[i], "-schema")) ||
   3415 	         (!strcmp(argv[i], "--schema"))) {
   3416 	    i++;
   3417 	    schema = argv[i];
   3418 	    noent++;
   3419 #endif
   3420 #ifdef LIBXML_SCHEMATRON_ENABLED
   3421 	} else if ((!strcmp(argv[i], "-schematron")) ||
   3422 	         (!strcmp(argv[i], "--schematron"))) {
   3423 	    i++;
   3424 	    schematron = argv[i];
   3425 	    noent++;
   3426 #endif
   3427         } else if ((!strcmp(argv[i], "-nonet")) ||
   3428                    (!strcmp(argv[i], "--nonet"))) {
   3429 	    options |= XML_PARSE_NONET;
   3430 	    xmlSetExternalEntityLoader(xmlNoNetExternalEntityLoader);
   3431         } else if ((!strcmp(argv[i], "-nocompact")) ||
   3432                    (!strcmp(argv[i], "--nocompact"))) {
   3433 	    options &= ~XML_PARSE_COMPACT;
   3434 	} else if ((!strcmp(argv[i], "-load-trace")) ||
   3435 	           (!strcmp(argv[i], "--load-trace"))) {
   3436 	    load_trace++;
   3437         } else if ((!strcmp(argv[i], "-path")) ||
   3438                    (!strcmp(argv[i], "--path"))) {
   3439 	    i++;
   3440 	    parsePath(BAD_CAST argv[i]);
   3441 #ifdef LIBXML_PATTERN_ENABLED
   3442         } else if ((!strcmp(argv[i], "-pattern")) ||
   3443                    (!strcmp(argv[i], "--pattern"))) {
   3444 	    i++;
   3445 	    pattern = argv[i];
   3446 #endif
   3447 #ifdef LIBXML_XPATH_ENABLED
   3448         } else if ((!strcmp(argv[i], "-xpath")) ||
   3449                    (!strcmp(argv[i], "--xpath"))) {
   3450 	    i++;
   3451 	    noout++;
   3452 	    xpathquery = argv[i];
   3453 #endif
   3454 	} else if ((!strcmp(argv[i], "-oldxml10")) ||
   3455 	           (!strcmp(argv[i], "--oldxml10"))) {
   3456 	    oldxml10++;
   3457 	    options |= XML_PARSE_OLD10;
   3458 	} else {
   3459 	    fprintf(stderr, "Unknown option %s\n", argv[i]);
   3460 	    usage(argv[0]);
   3461 	    return(1);
   3462 	}
   3463     }
   3464 
   3465 #ifdef LIBXML_CATALOG_ENABLED
   3466     if (nocatalogs == 0) {
   3467 	if (catalogs) {
   3468 	    const char *catal;
   3469 
   3470 	    catal = getenv("SGML_CATALOG_FILES");
   3471 	    if (catal != NULL) {
   3472 		xmlLoadCatalogs(catal);
   3473 	    } else {
   3474 		fprintf(stderr, "Variable $SGML_CATALOG_FILES not set\n");
   3475 	    }
   3476 	}
   3477     }
   3478 #endif
   3479 
   3480 #ifdef LIBXML_SAX1_ENABLED
   3481     if (sax1)
   3482         xmlSAXDefaultVersion(1);
   3483     else
   3484         xmlSAXDefaultVersion(2);
   3485 #endif /* LIBXML_SAX1_ENABLED */
   3486 
   3487     if (chkregister) {
   3488 	xmlRegisterNodeDefault(registerNode);
   3489 	xmlDeregisterNodeDefault(deregisterNode);
   3490     }
   3491 
   3492     indent = getenv("XMLLINT_INDENT");
   3493     if(indent != NULL) {
   3494 	xmlTreeIndentString = indent;
   3495     }
   3496 
   3497 
   3498     defaultEntityLoader = xmlGetExternalEntityLoader();
   3499     xmlSetExternalEntityLoader(xmllintExternalEntityLoader);
   3500 
   3501     xmlLineNumbersDefault(1);
   3502     if (loaddtd != 0)
   3503 	xmlLoadExtDtdDefaultValue |= XML_DETECT_IDS;
   3504     if (dtdattrs)
   3505 	xmlLoadExtDtdDefaultValue |= XML_COMPLETE_ATTRS;
   3506     if (noent != 0) xmlSubstituteEntitiesDefault(1);
   3507 #ifdef LIBXML_VALID_ENABLED
   3508     if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
   3509 #endif /* LIBXML_VALID_ENABLED */
   3510     if ((htmlout) && (!nowrap)) {
   3511 	xmlGenericError(xmlGenericErrorContext,
   3512          "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
   3513 	xmlGenericError(xmlGenericErrorContext,
   3514 		"\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
   3515 	xmlGenericError(xmlGenericErrorContext,
   3516 	 "<html><head><title>%s output</title></head>\n",
   3517 		argv[0]);
   3518 	xmlGenericError(xmlGenericErrorContext,
   3519 	 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
   3520 		argv[0]);
   3521     }
   3522 
   3523 #ifdef LIBXML_SCHEMATRON_ENABLED
   3524     if ((schematron != NULL) && (sax == 0)
   3525 #ifdef LIBXML_READER_ENABLED
   3526         && (stream == 0)
   3527 #endif /* LIBXML_READER_ENABLED */
   3528 	) {
   3529 	xmlSchematronParserCtxtPtr ctxt;
   3530 
   3531         /* forces loading the DTDs */
   3532         xmlLoadExtDtdDefaultValue |= 1;
   3533 	options |= XML_PARSE_DTDLOAD;
   3534 	if (timing) {
   3535 	    startTimer();
   3536 	}
   3537 	ctxt = xmlSchematronNewParserCtxt(schematron);
   3538 #if 0
   3539 	xmlSchematronSetParserErrors(ctxt,
   3540 		(xmlSchematronValidityErrorFunc) fprintf,
   3541 		(xmlSchematronValidityWarningFunc) fprintf,
   3542 		stderr);
   3543 #endif
   3544 	wxschematron = xmlSchematronParse(ctxt);
   3545 	if (wxschematron == NULL) {
   3546 	    xmlGenericError(xmlGenericErrorContext,
   3547 		    "Schematron schema %s failed to compile\n", schematron);
   3548             progresult = XMLLINT_ERR_SCHEMACOMP;
   3549 	    schematron = NULL;
   3550 	}
   3551 	xmlSchematronFreeParserCtxt(ctxt);
   3552 	if (timing) {
   3553 	    endTimer("Compiling the schemas");
   3554 	}
   3555     }
   3556 #endif
   3557 #ifdef LIBXML_SCHEMAS_ENABLED
   3558     if ((relaxng != NULL) && (sax == 0)
   3559 #ifdef LIBXML_READER_ENABLED
   3560         && (stream == 0)
   3561 #endif /* LIBXML_READER_ENABLED */
   3562 	) {
   3563 	xmlRelaxNGParserCtxtPtr ctxt;
   3564 
   3565         /* forces loading the DTDs */
   3566         xmlLoadExtDtdDefaultValue |= 1;
   3567 	options |= XML_PARSE_DTDLOAD;
   3568 	if (timing) {
   3569 	    startTimer();
   3570 	}
   3571 	ctxt = xmlRelaxNGNewParserCtxt(relaxng);
   3572 	xmlRelaxNGSetParserErrors(ctxt,
   3573 		(xmlRelaxNGValidityErrorFunc) fprintf,
   3574 		(xmlRelaxNGValidityWarningFunc) fprintf,
   3575 		stderr);
   3576 	relaxngschemas = xmlRelaxNGParse(ctxt);
   3577 	if (relaxngschemas == NULL) {
   3578 	    xmlGenericError(xmlGenericErrorContext,
   3579 		    "Relax-NG schema %s failed to compile\n", relaxng);
   3580             progresult = XMLLINT_ERR_SCHEMACOMP;
   3581 	    relaxng = NULL;
   3582 	}
   3583 	xmlRelaxNGFreeParserCtxt(ctxt);
   3584 	if (timing) {
   3585 	    endTimer("Compiling the schemas");
   3586 	}
   3587     } else if ((schema != NULL)
   3588 #ifdef LIBXML_READER_ENABLED
   3589 		&& (stream == 0)
   3590 #endif
   3591 	) {
   3592 	xmlSchemaParserCtxtPtr ctxt;
   3593 
   3594 	if (timing) {
   3595 	    startTimer();
   3596 	}
   3597 	ctxt = xmlSchemaNewParserCtxt(schema);
   3598 	xmlSchemaSetParserErrors(ctxt,
   3599 		(xmlSchemaValidityErrorFunc) fprintf,
   3600 		(xmlSchemaValidityWarningFunc) fprintf,
   3601 		stderr);
   3602 	wxschemas = xmlSchemaParse(ctxt);
   3603 	if (wxschemas == NULL) {
   3604 	    xmlGenericError(xmlGenericErrorContext,
   3605 		    "WXS schema %s failed to compile\n", schema);
   3606             progresult = XMLLINT_ERR_SCHEMACOMP;
   3607 	    schema = NULL;
   3608 	}
   3609 	xmlSchemaFreeParserCtxt(ctxt);
   3610 	if (timing) {
   3611 	    endTimer("Compiling the schemas");
   3612 	}
   3613     }
   3614 #endif /* LIBXML_SCHEMAS_ENABLED */
   3615 #ifdef LIBXML_PATTERN_ENABLED
   3616     if ((pattern != NULL)
   3617 #ifdef LIBXML_READER_ENABLED
   3618         && (walker == 0)
   3619 #endif
   3620 	) {
   3621         patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
   3622 	if (patternc == NULL) {
   3623 	    xmlGenericError(xmlGenericErrorContext,
   3624 		    "Pattern %s failed to compile\n", pattern);
   3625             progresult = XMLLINT_ERR_SCHEMAPAT;
   3626 	    pattern = NULL;
   3627 	}
   3628     }
   3629 #endif /* LIBXML_PATTERN_ENABLED */
   3630     for (i = 1; i < argc ; i++) {
   3631 	if ((!strcmp(argv[i], "-encode")) ||
   3632 	         (!strcmp(argv[i], "--encode"))) {
   3633 	    i++;
   3634 	    continue;
   3635         } else if ((!strcmp(argv[i], "-o")) ||
   3636                    (!strcmp(argv[i], "-output")) ||
   3637                    (!strcmp(argv[i], "--output"))) {
   3638             i++;
   3639 	    continue;
   3640         }
   3641 #ifdef LIBXML_VALID_ENABLED
   3642 	if ((!strcmp(argv[i], "-dtdvalid")) ||
   3643 	         (!strcmp(argv[i], "--dtdvalid"))) {
   3644 	    i++;
   3645 	    continue;
   3646         }
   3647 	if ((!strcmp(argv[i], "-path")) ||
   3648                    (!strcmp(argv[i], "--path"))) {
   3649             i++;
   3650 	    continue;
   3651         }
   3652 	if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
   3653 	         (!strcmp(argv[i], "--dtdvalidfpi"))) {
   3654 	    i++;
   3655 	    continue;
   3656         }
   3657 #endif /* LIBXML_VALID_ENABLED */
   3658 	if ((!strcmp(argv[i], "-relaxng")) ||
   3659 	         (!strcmp(argv[i], "--relaxng"))) {
   3660 	    i++;
   3661 	    continue;
   3662         }
   3663 	if ((!strcmp(argv[i], "-maxmem")) ||
   3664 	         (!strcmp(argv[i], "--maxmem"))) {
   3665 	    i++;
   3666 	    continue;
   3667         }
   3668 	if ((!strcmp(argv[i], "-pretty")) ||
   3669 	         (!strcmp(argv[i], "--pretty"))) {
   3670 	    i++;
   3671 	    continue;
   3672         }
   3673 	if ((!strcmp(argv[i], "-schema")) ||
   3674 	         (!strcmp(argv[i], "--schema"))) {
   3675 	    i++;
   3676 	    continue;
   3677         }
   3678 	if ((!strcmp(argv[i], "-schematron")) ||
   3679 	         (!strcmp(argv[i], "--schematron"))) {
   3680 	    i++;
   3681 	    continue;
   3682         }
   3683 #ifdef LIBXML_PATTERN_ENABLED
   3684         if ((!strcmp(argv[i], "-pattern")) ||
   3685 	    (!strcmp(argv[i], "--pattern"))) {
   3686 	    i++;
   3687 	    continue;
   3688 	}
   3689 #endif
   3690 #ifdef LIBXML_XPATH_ENABLED
   3691         if ((!strcmp(argv[i], "-xpath")) ||
   3692 	    (!strcmp(argv[i], "--xpath"))) {
   3693 	    i++;
   3694 	    continue;
   3695 	}
   3696 #endif
   3697 	if ((timing) && (repeat))
   3698 	    startTimer();
   3699 	/* Remember file names.  "-" means stdin.  <sven (at) zen.org> */
   3700 	if ((argv[i][0] != '-') || (strcmp(argv[i], "-") == 0)) {
   3701 	    if (repeat) {
   3702 		xmlParserCtxtPtr ctxt = NULL;
   3703 
   3704 		for (acount = 0;acount < repeat;acount++) {
   3705 #ifdef LIBXML_READER_ENABLED
   3706 		    if (stream != 0) {
   3707 			streamFile(argv[i]);
   3708 		    } else {
   3709 #endif /* LIBXML_READER_ENABLED */
   3710                         if (sax) {
   3711 			    testSAX(argv[i]);
   3712 			} else {
   3713 			    if (ctxt == NULL)
   3714 				ctxt = xmlNewParserCtxt();
   3715 			    parseAndPrintFile(argv[i], ctxt);
   3716 			}
   3717 #ifdef LIBXML_READER_ENABLED
   3718 		    }
   3719 #endif /* LIBXML_READER_ENABLED */
   3720 		}
   3721 		if (ctxt != NULL)
   3722 		    xmlFreeParserCtxt(ctxt);
   3723 	    } else {
   3724 		nbregister = 0;
   3725 
   3726 #ifdef LIBXML_READER_ENABLED
   3727 		if (stream != 0)
   3728 		    streamFile(argv[i]);
   3729 		else
   3730 #endif /* LIBXML_READER_ENABLED */
   3731                 if (sax) {
   3732 		    testSAX(argv[i]);
   3733 		} else {
   3734 		    parseAndPrintFile(argv[i], NULL);
   3735 		}
   3736 
   3737                 if ((chkregister) && (nbregister != 0)) {
   3738 		    fprintf(stderr, "Registration count off: %d\n", nbregister);
   3739 		    progresult = XMLLINT_ERR_RDREGIS;
   3740 		}
   3741 	    }
   3742 	    files ++;
   3743 	    if ((timing) && (repeat)) {
   3744 		endTimer("%d iterations", repeat);
   3745 	    }
   3746 	}
   3747     }
   3748     if (generate)
   3749 	parseAndPrintFile(NULL, NULL);
   3750     if ((htmlout) && (!nowrap)) {
   3751 	xmlGenericError(xmlGenericErrorContext, "</body></html>\n");
   3752     }
   3753     if ((files == 0) && (!generate) && (version == 0)) {
   3754 	usage(argv[0]);
   3755     }
   3756 #ifdef LIBXML_SCHEMATRON_ENABLED
   3757     if (wxschematron != NULL)
   3758 	xmlSchematronFree(wxschematron);
   3759 #endif
   3760 #ifdef LIBXML_SCHEMAS_ENABLED
   3761     if (relaxngschemas != NULL)
   3762 	xmlRelaxNGFree(relaxngschemas);
   3763     if (wxschemas != NULL)
   3764 	xmlSchemaFree(wxschemas);
   3765     xmlRelaxNGCleanupTypes();
   3766 #endif
   3767 #ifdef LIBXML_PATTERN_ENABLED
   3768     if (patternc != NULL)
   3769         xmlFreePattern(patternc);
   3770 #endif
   3771     xmlCleanupParser();
   3772     xmlMemoryDump();
   3773 
   3774     return(progresult);
   3775 }
   3776 
   3777