xmllint: Stop using global variables

The only exception is "maxmem". The custom malloc functions don't
support an extra context.
diff --git a/xmllint.c b/xmllint.c
index 35923de..76af748 100644
--- a/xmllint.c
+++ b/xmllint.c
@@ -12,13 +12,9 @@
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <assert.h>
-#include <time.h>
 #include <errno.h>
 #include <limits.h>
-
 #include <fcntl.h>
-#include <sys/stat.h>
 
 #ifdef _WIN32
   #include <io.h>
@@ -30,6 +26,7 @@
 
 #if HAVE_DECL_MMAP
   #include <sys/mman.h>
+  #include <sys/stat.h>
   /* seems needed for Solaris */
   #ifndef MAP_FAILED
     #define MAP_FAILED ((void *) -1)
@@ -81,6 +78,19 @@
 #ifndef STDIN_FILENO
   #define STDIN_FILENO 0
 #endif
+#ifndef STDOUT_FILENO
+  #define STDOUT_FILENO 1
+#endif
+
+#define MAX_PATHS 64
+
+#ifdef _WIN32
+  #define PATH_SEPARATOR ';'
+#else
+  #define PATH_SEPARATOR ':'
+#endif
+
+#define HTML_BUF_SIZE 50000
 
 typedef enum {
     XMLLINT_RETURN_OK = 0,	    /* No error */
@@ -97,103 +107,130 @@
     XMLLINT_ERR_XPATH_EMPTY = 11    /* XPath result is empty */
 } xmllintReturnCode;
 
-static int shell = 0;
-#ifdef LIBXML_DEBUG_ENABLED
-static int debugent = 0;
+#ifdef _WIN32
+typedef __time64_t xmlSeconds;
+#else
+typedef time_t xmlSeconds;
 #endif
-static int debug = 0;
-static int maxmem = 0;
-static int copy = 0;
-static int noout = 0;
+
+typedef struct {
+   xmlSeconds sec;
+   int usec;
+} xmlTime;
+
+typedef struct {
+    xmlParserCtxtPtr ctxt;
+    xmlResourceLoader defaultResourceLoader;
+
+    int version;
+    int nowrap;
+    int sax;
+    int callbacks;
+    int shell;
+#ifdef LIBXML_DEBUG_ENABLED
+    int debugent;
+#endif
+    int debug;
+    int copy;
+    int noout;
 #ifdef LIBXML_OUTPUT_ENABLED
-static const char *output = NULL;
-static int format = 0;
-static const char *encoding = NULL;
-static int compress = 0;
+    const char *output;
+    int format;
+    const char *encoding;
+    int compress;
 #endif /* LIBXML_OUTPUT_ENABLED */
 #ifdef LIBXML_VALID_ENABLED
-static int postvalid = 0;
-static const char *dtdvalid = NULL;
-static const char *dtdvalidfpi = NULL;
-static int insert = 0;
+    int postvalid;
+    const char *dtdvalid;
+    const char *dtdvalidfpi;
+    int insert;
 #endif
 #ifdef LIBXML_SCHEMAS_ENABLED
-static const char *relaxng = NULL;
-static xmlRelaxNGPtr relaxngschemas = NULL;
-static const char *schema = NULL;
-static xmlSchemaPtr wxschemas = NULL;
+    const char *relaxng;
+    xmlRelaxNGPtr relaxngschemas;
+    const char *schema;
+    xmlSchemaPtr wxschemas;
 #endif
 #ifdef LIBXML_SCHEMATRON_ENABLED
-static const char *schematron = NULL;
-static xmlSchematronPtr wxschematron = NULL;
+    const char *schematron;
+    xmlSchematronPtr wxschematron;
 #endif
-static int repeat = 1;
+    int repeat;
 #if defined(LIBXML_HTML_ENABLED)
-static int html = 0;
-static int xmlout = 0;
+    int html;
+    int xmlout;
 #endif
-static int htmlout = 0;
+    int htmlout;
 #ifdef LIBXML_PUSH_ENABLED
-static int push = 0;
-static const int pushsize = 4096;
+    int push;
+    const int pushsize;
 #endif /* LIBXML_PUSH_ENABLED */
 #if HAVE_DECL_MMAP
-static int memory = 0;
-static char *memoryData;
-static size_t memorySize;
+    int memory;
+    char *memoryData;
+    size_t memorySize;
 #endif
-static int testIO = 0;
+    int testIO;
 #ifdef LIBXML_XINCLUDE_ENABLED
-static int xinclude = 0;
+    int xinclude;
 #endif
-static xmllintReturnCode progresult = XMLLINT_RETURN_OK;
-static int quiet = 0;
-static int timing = 0;
-static int generate = 0;
-static int dropdtd = 0;
+    xmllintReturnCode progresult;
+    int quiet;
+    int timing;
+    int generate;
+    int dropdtd;
 #ifdef LIBXML_C14N_ENABLED
-static int canonical = 0;
-static int canonical_11 = 0;
-static int exc_canonical = 0;
+    int canonical;
+    int canonical_11;
+    int exc_canonical;
 #endif
 #ifdef LIBXML_READER_ENABLED
-static int walker = 0;
+    int stream;
+    int walker;
 #ifdef LIBXML_PATTERN_ENABLED
-static const char *pattern = NULL;
-static xmlPatternPtr patternc = NULL;
-static xmlStreamCtxtPtr patstream = NULL;
+    const char *pattern;
+    xmlPatternPtr patternc;
+    xmlStreamCtxtPtr patstream;
 #endif
 #endif /* LIBXML_READER_ENABLED */
 #ifdef LIBXML_XPATH_ENABLED
-static const char *xpathquery = NULL;
+    const char *xpathquery;
 #endif
-static int options = XML_PARSE_COMPACT | XML_PARSE_BIG_LINES;
-static unsigned maxAmpl = 0;
+#ifdef LIBXML_CATALOG_ENABLED
+    int catalogs;
+    int nocatalogs;
+#endif
+    int options;
+    unsigned maxAmpl;
+
+    xmlChar *paths[MAX_PATHS + 1];
+    int nbpaths;
+    int load_trace;
+
+    char *htmlBuf;
+    int htmlBufLen;
+
+    xmlTime begin, end;
+} xmllintState;
+
+static int xmllintMaxmem;
 
 /************************************************************************
  *									*
  *		 Entity loading control and customization.		*
  *									*
  ************************************************************************/
-#define MAX_PATHS 64
-#ifdef _WIN32
-# define PATH_SEPARATOR ';'
-#else
-# define PATH_SEPARATOR ':'
-#endif
-static xmlChar *paths[MAX_PATHS + 1];
-static int nbpaths = 0;
-static int load_trace = 0;
 
-static
-void parsePath(const xmlChar *path) {
+static void
+parsePath(xmllintState *lint, const xmlChar *path) {
     const xmlChar *cur;
 
     if (path == NULL)
 	return;
     while (*path != 0) {
-	if (nbpaths >= MAX_PATHS) {
+	if (lint->nbpaths >= MAX_PATHS) {
 	    fprintf(ERR_STREAM, "MAX_PATHS reached: too many paths\n");
+            lint->progresult = XMLLINT_ERR_UNCLASS;
 	    return;
 	}
 	cur = path;
@@ -203,26 +240,25 @@
 	while ((*cur != 0) && (*cur != ' ') && (*cur != PATH_SEPARATOR))
 	    cur++;
 	if (cur != path) {
-	    paths[nbpaths] = xmlStrndup(path, cur - path);
-	    if (paths[nbpaths] != NULL)
-		nbpaths++;
+	    lint->paths[lint->nbpaths] = xmlStrndup(path, cur - path);
+	    if (lint->paths[lint->nbpaths] != NULL)
+		lint->nbpaths++;
 	    path = cur;
 	}
     }
 }
 
-static xmlResourceLoader defaultResourceLoader = NULL;
-
 static int
-xmllintResourceLoader(void *ctxt ATTRIBUTE_UNUSED, const char *URL,
+xmllintResourceLoader(void *ctxt, const char *URL,
                       const char *ID, xmlResourceType type, int flags,
 		      xmlParserInputPtr *out) {
+    xmllintState *lint = ctxt;
     int code;
     int i;
     const char *lastsegment = URL;
     const char *iter = URL;
 
-    if ((nbpaths > 0) && (iter != NULL)) {
+    if ((lint->nbpaths > 0) && (iter != NULL)) {
 	while (*iter != 0) {
 	    if (*iter == '/')
 		lastsegment = iter + 1;
@@ -230,32 +266,32 @@
 	}
     }
 
-    if (defaultResourceLoader != NULL)
-        code = defaultResourceLoader(NULL, URL, ID, type, flags, out);
+    if (lint->defaultResourceLoader != NULL)
+        code = lint->defaultResourceLoader(NULL, URL, ID, type, flags, out);
     else
         code = xmlNewInputFromUrl(URL, flags, out);
     if (code != XML_IO_ENOENT) {
-        if ((load_trace) && (code == XML_ERR_OK)) {
+        if ((lint->load_trace) && (code == XML_ERR_OK)) {
             fprintf(ERR_STREAM, "Loaded URL=\"%s\" ID=\"%s\"\n",
                     URL, ID ? ID : "(null)");
         }
         return(code);
     }
 
-    for (i = 0; i < nbpaths; i++) {
+    for (i = 0; i < lint->nbpaths; i++) {
 	xmlChar *newURL;
 
-	newURL = xmlStrdup((const xmlChar *) paths[i]);
+	newURL = xmlStrdup((const xmlChar *) lint->paths[i]);
 	newURL = xmlStrcat(newURL, (const xmlChar *) "/");
 	newURL = xmlStrcat(newURL, (const xmlChar *) lastsegment);
 	if (newURL != NULL) {
-            if (defaultResourceLoader != NULL)
-                code = defaultResourceLoader(NULL, (const char *) newURL, ID,
-                                             type, flags, out);
+            if (lint->defaultResourceLoader != NULL)
+                code = lint->defaultResourceLoader(NULL, (const char *) newURL,
+                                                   ID, type, flags, out);
             else
                 code = xmlNewInputFromUrl((const char *) newURL, flags, out);
             if (code != XML_IO_ENOENT) {
-                if ((load_trace) && (code == XML_ERR_OK)) {
+                if ((lint->load_trace) && (code == XML_ERR_OK)) {
                     fprintf(ERR_STREAM, "Loaded URL=\"%s\" ID=\"%s\"\n",
                             newURL, ID ? ID : "(null)");
                 }
@@ -289,30 +325,31 @@
 }
 
 static xmlDocPtr
-parseXml(xmlParserCtxtPtr ctxt, const char *filename) {
+parseXml(xmllintState *lint, const char *filename) {
     xmlDocPtr doc;
 
-    xmlCtxtSetResourceLoader(ctxt, xmllintResourceLoader, NULL);
-    if (maxAmpl > 0)
-        xmlCtxtSetMaxAmplification(ctxt, maxAmpl);
+    xmlCtxtSetResourceLoader(lint->ctxt, xmllintResourceLoader, lint);
+    if (lint->maxAmpl > 0)
+        xmlCtxtSetMaxAmplification(lint->ctxt, lint->maxAmpl);
 
 #if HAVE_DECL_MMAP
-    if (memory) {
+    if (lint->memory) {
         xmlParserInputPtr input;
 
-        input = xmlNewInputFromMemory(filename, memoryData, memorySize,
+        input = xmlNewInputFromMemory(filename,
+                                      lint->memoryData, lint->memorySize,
                                       XML_INPUT_BUF_STATIC |
                                       XML_INPUT_BUF_ZERO_TERMINATED);
         if (input == NULL) {
-            progresult = XMLLINT_ERR_MEM;
+            lint->progresult = XMLLINT_ERR_MEM;
             return(NULL);
         }
-        doc = xmlCtxtParseDocument(ctxt, input);
+        doc = xmlCtxtParseDocument(lint->ctxt, input);
         return(doc);
     }
 #endif
 
-    if (testIO) {
+    if (lint->testIO) {
         FILE *f;
 
         if ((filename[0] == '-') && (filename[1] == 0)) {
@@ -321,18 +358,19 @@
             f = fopen(filename, "rb");
             if (f == NULL) {
                 fprintf(ERR_STREAM, "Can't open %s\n", filename);
-                progresult = XMLLINT_ERR_RDFILE;
+                lint->progresult = XMLLINT_ERR_RDFILE;
                 return(NULL);
             }
         }
 
-        doc = xmlCtxtReadIO(ctxt, myRead, myClose, f, filename, NULL,
-                            options);
+        doc = xmlCtxtReadIO(lint->ctxt, myRead, myClose, f, filename, NULL,
+                            lint->options);
     } else {
         if (strcmp(filename, "-") == 0)
-            doc = xmlCtxtReadFd(ctxt, STDIN_FILENO, "-", NULL, options);
+            doc = xmlCtxtReadFd(lint->ctxt, STDIN_FILENO, "-", NULL,
+                                lint->options);
         else
-            doc = xmlCtxtReadFile(ctxt, filename, NULL, options);
+            doc = xmlCtxtReadFile(lint->ctxt, filename, NULL, lint->options);
     }
 
     return(doc);
@@ -340,29 +378,31 @@
 
 #ifdef LIBXML_HTML_ENABLED
 static xmlDocPtr
-parseHtml(htmlParserCtxtPtr ctxt, const char *filename) {
+parseHtml(xmllintState *lint, const char *filename) {
     xmlDocPtr doc;
 
 #if HAVE_DECL_MMAP
-    if (memory) {
+    if (lint->memory) {
         xmlParserInputPtr input;
 
-        input = xmlNewInputFromMemory(filename, memoryData, memorySize,
+        input = xmlNewInputFromMemory(filename,
+                                      lint->memoryData, lint->memorySize,
                                       XML_INPUT_BUF_STATIC |
                                       XML_INPUT_BUF_ZERO_TERMINATED);
         if (input == NULL) {
-            progresult = XMLLINT_ERR_MEM;
+            lint->progresult = XMLLINT_ERR_MEM;
             return(NULL);
         }
-        doc = htmlCtxtParseDocument(ctxt, input);
+        doc = htmlCtxtParseDocument(lint->ctxt, input);
         return(doc);
     }
 #endif
 
     if (strcmp(filename, "-") == 0)
-        doc = htmlCtxtReadFd(ctxt, STDIN_FILENO, "-", NULL, options);
+        doc = htmlCtxtReadFd(lint->ctxt, STDIN_FILENO, "-", NULL,
+                             lint->options);
     else
-        doc = htmlCtxtReadFile(ctxt, filename, NULL, options);
+        doc = htmlCtxtReadFile(lint->ctxt, filename, NULL, lint->options);
 
     return(doc);
 }
@@ -377,8 +417,8 @@
 static void
 OOM(void)
 {
-    fprintf(ERR_STREAM, "Ran out of memory needs > %d bytes\n", maxmem);
-    progresult = XMLLINT_ERR_MEM;
+    fprintf(ERR_STREAM, "Ran out of memory needs > %d bytes\n",
+            xmllintMaxmem);
 }
 
 static void
@@ -393,7 +433,7 @@
 
     ret = xmlMemMalloc(size);
     if (ret != NULL) {
-        if (xmlMemUsed() > maxmem) {
+        if (xmlMemUsed() > xmllintMaxmem) {
             OOM();
             xmlMemFree(ret);
             return (NULL);
@@ -406,7 +446,7 @@
 {
     size_t oldsize = xmlMemSize(mem);
 
-    if (xmlMemUsed() + size - oldsize > (size_t) maxmem) {
+    if (xmlMemUsed() + size - oldsize > (size_t) xmllintMaxmem) {
         OOM();
         return (NULL);
     }
@@ -420,7 +460,7 @@
 
     ret = xmlMemoryStrdup(str);
     if (ret != NULL) {
-        if (xmlMemUsed() > maxmem) {
+        if (xmlMemUsed() > xmllintMaxmem) {
             OOM();
             xmlMemFree(ret);
             return (NULL);
@@ -428,6 +468,7 @@
     }
     return (ret);
 }
+
 /************************************************************************
  *									*
  * Internal timing routines to remove the necessity to have		*
@@ -435,19 +476,6 @@
  *									*
  ************************************************************************/
 
-#ifdef _WIN32
-typedef __time64_t xmlSeconds;
-#else
-typedef time_t xmlSeconds;
-#endif
-
-typedef struct {
-   xmlSeconds sec;
-   int usec;
-} xmlTime;
-
-static xmlTime begin, end;
-
 static void
 getTime(xmlTime *time) {
 #ifdef _WIN32
@@ -469,9 +497,9 @@
  * startTimer: call where you want to start timing
  */
 static void
-startTimer(void)
+startTimer(xmllintState *lint)
 {
-    getTime(&begin);
+    getTime(&lint->begin);
 }
 
 /*
@@ -479,16 +507,16 @@
  *           message about the timing performed; format is a printf
  *           type argument
  */
-static void LIBXML_ATTR_FORMAT(1,2)
-endTimer(const char *fmt, ...)
+static void LIBXML_ATTR_FORMAT(2,3)
+endTimer(xmllintState *lint, const char *fmt, ...)
 {
     xmlSeconds msec;
     va_list ap;
 
-    getTime(&end);
-    msec = end.sec - begin.sec;
+    getTime(&lint->end);
+    msec = lint->end.sec - lint->begin.sec;
     msec *= 1000;
-    msec += (end.usec - begin.usec) / 1000;
+    msec += (lint->end.usec - lint->begin.usec) / 1000;
 
     va_start(ap, fmt);
     vfprintf(ERR_STREAM, fmt, ap);
@@ -502,11 +530,9 @@
  *			HTML output					*
  *									*
  ************************************************************************/
-static char buffer[50000];
-static int htmlBufLen;
 
 static void
-xmlHTMLEncodeSend(void) {
+xmlHTMLEncodeSend(xmllintState *lint) {
     char *result;
 
     /*
@@ -514,30 +540,32 @@
      * end with a truncated UTF-8 sequence. This is a hack to at least avoid
      * an out-of-bounds read.
      */
-    memset(&buffer[sizeof(buffer)-4], 0, 4);
-    result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
+    memset(&lint->htmlBuf[HTML_BUF_SIZE - 4], 0, 4);
+    result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST lint->htmlBuf);
     if (result) {
 	fprintf(ERR_STREAM, "%s", result);
 	xmlFree(result);
     }
 
-    htmlBufLen = 0;
+    lint->htmlBufLen = 0;
 }
 
 static void
-xmlHTMLBufCat(void *data ATTRIBUTE_UNUSED, const char *fmt, ...) {
+xmlHTMLBufCat(void *data, const char *fmt, ...) {
+    xmllintState *lint = data;
     va_list ap;
     int res;
 
     va_start(ap, fmt);
-    res = vsnprintf(&buffer[htmlBufLen], sizeof(buffer) - htmlBufLen, fmt, ap);
+    res = vsnprintf(&lint->htmlBuf[lint->htmlBufLen],
+                    HTML_BUF_SIZE - lint->htmlBufLen, fmt, ap);
     va_end(ap);
 
     if (res > 0) {
-        if ((size_t) res > sizeof(buffer) - htmlBufLen - 1)
-            htmlBufLen = sizeof(buffer) - 1;
+        if (res > HTML_BUF_SIZE - lint->htmlBufLen - 1)
+            lint->htmlBufLen = HTML_BUF_SIZE - 1;
         else
-            htmlBufLen += res;
+            lint->htmlBufLen += res;
     }
 }
 
@@ -553,7 +581,8 @@
 static void
 xmlHTMLError(void *vctxt, const xmlError *error)
 {
-    xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) vctxt;
+    xmlParserCtxtPtr ctxt = vctxt;
+    xmllintState *lint = ctxt->_private;
     xmlParserInputPtr input;
     xmlGenericErrorFunc oldError;
     void *oldErrorCtxt;
@@ -565,20 +594,20 @@
 
     oldError = xmlGenericError;
     oldErrorCtxt = xmlGenericErrorContext;
-    xmlSetGenericErrorFunc(NULL, xmlHTMLBufCat);
+    xmlSetGenericErrorFunc(lint, xmlHTMLBufCat);
 
     fprintf(ERR_STREAM, "<p>");
 
     xmlParserPrintFileInfo(input);
-    xmlHTMLEncodeSend();
+    xmlHTMLEncodeSend(lint);
 
     fprintf(ERR_STREAM, "<b>%s%s</b>: ",
             (error->domain == XML_FROM_VALID) ||
             (error->domain == XML_FROM_DTD) ? "validity " : "",
             error->level == XML_ERR_WARNING ? "warning" : "error");
 
-    snprintf(buffer, sizeof(buffer), "%s", error->message);
-    xmlHTMLEncodeSend();
+    snprintf(lint->htmlBuf, HTML_BUF_SIZE, "%s", error->message);
+    xmlHTMLEncodeSend(lint);
 
     fprintf(ERR_STREAM, "</p>\n");
 
@@ -586,7 +615,7 @@
         fprintf(ERR_STREAM, "<pre>\n");
 
         xmlParserPrintFileContext(input);
-        xmlHTMLEncodeSend();
+        xmlHTMLEncodeSend(lint);
 
         fprintf(ERR_STREAM, "</pre>");
     }
@@ -603,7 +632,7 @@
 /*
  * empty SAX block
  */
-static xmlSAXHandler emptySAXHandlerStruct = {
+static const xmlSAXHandler emptySAXHandler = {
     NULL, /* internalSubset */
     NULL, /* isStandalone */
     NULL, /* hasInternalSubset */
@@ -638,10 +667,6 @@
     NULL  /* xmlStructuredErrorFunc */
 };
 
-static xmlSAXHandlerPtr emptySAXHandler = &emptySAXHandlerStruct;
-extern xmlSAXHandlerPtr debugSAXHandler;
-static int callbacks;
-
 /**
  * isStandaloneDebug:
  * @ctxt:  An XML parser context
@@ -651,10 +676,12 @@
  * Returns 1 if true
  */
 static int
-isStandaloneDebug(void *ctx ATTRIBUTE_UNUSED)
+isStandaloneDebug(void *ctx)
 {
-    callbacks++;
-    if (noout)
+    xmllintState *lint = ctx;
+
+    lint->callbacks++;
+    if (lint->noout)
 	return(0);
     fprintf(stdout, "SAX.isStandalone()\n");
     return(0);
@@ -669,10 +696,12 @@
  * Returns 1 if true
  */
 static int
-hasInternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
+hasInternalSubsetDebug(void *ctx)
 {
-    callbacks++;
-    if (noout)
+    xmllintState *lint = ctx;
+
+    lint->callbacks++;
+    if (lint->noout)
 	return(0);
     fprintf(stdout, "SAX.hasInternalSubset()\n");
     return(0);
@@ -687,10 +716,12 @@
  * Returns 1 if true
  */
 static int
-hasExternalSubsetDebug(void *ctx ATTRIBUTE_UNUSED)
+hasExternalSubsetDebug(void *ctx)
 {
-    callbacks++;
-    if (noout)
+    xmllintState *lint = ctx;
+
+    lint->callbacks++;
+    if (lint->noout)
 	return(0);
     fprintf(stdout, "SAX.hasExternalSubset()\n");
     return(0);
@@ -703,11 +734,13 @@
  * Does this document has an internal subset
  */
 static void
-internalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
+internalSubsetDebug(void *ctx, const xmlChar *name,
 	       const xmlChar *ExternalID, const xmlChar *SystemID)
 {
-    callbacks++;
-    if (noout)
+    xmllintState *lint = ctx;
+
+    lint->callbacks++;
+    if (lint->noout)
 	return;
     fprintf(stdout, "SAX.internalSubset(%s,", name);
     if (ExternalID == NULL)
@@ -727,11 +760,13 @@
  * Does this document has an external subset
  */
 static void
-externalSubsetDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
+externalSubsetDebug(void *ctx, const xmlChar *name,
 	       const xmlChar *ExternalID, const xmlChar *SystemID)
 {
-    callbacks++;
-    if (noout)
+    xmllintState *lint = ctx;
+
+    lint->callbacks++;
+    if (lint->noout)
 	return;
     fprintf(stdout, "SAX.externalSubset(%s,", name);
     if (ExternalID == NULL)
@@ -759,10 +794,12 @@
  * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
  */
 static xmlParserInputPtr
-resolveEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *publicId, const xmlChar *systemId)
+resolveEntityDebug(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
 {
-    callbacks++;
-    if (noout)
+    xmllintState *lint = ctx;
+
+    lint->callbacks++;
+    if (lint->noout)
 	return(NULL);
     /* xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; */
 
@@ -789,10 +826,12 @@
  * Returns the xmlParserInputPtr if inlined or NULL for DOM behaviour.
  */
 static xmlEntityPtr
-getEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
+getEntityDebug(void *ctx, const xmlChar *name)
 {
-    callbacks++;
-    if (noout)
+    xmllintState *lint = ctx;
+
+    lint->callbacks++;
+    if (lint->noout)
 	return(NULL);
     fprintf(stdout, "SAX.getEntity(%s)\n", name);
     return(NULL);
@@ -808,10 +847,12 @@
  * Returns the xmlParserInputPtr
  */
 static xmlEntityPtr
-getParameterEntityDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
+getParameterEntityDebug(void *ctx, const xmlChar *name)
 {
-    callbacks++;
-    if (noout)
+    xmllintState *lint = ctx;
+
+    lint->callbacks++;
+    if (lint->noout)
 	return(NULL);
     fprintf(stdout, "SAX.getParameterEntity(%s)\n", name);
     return(NULL);
@@ -830,10 +871,12 @@
  * An entity definition has been parsed
  */
 static void
-entityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
+entityDeclDebug(void *ctx, const xmlChar *name, int type,
           const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
 {
-const xmlChar *nullstr = BAD_CAST "(null)";
+    xmllintState *lint = ctx;
+    const xmlChar *nullstr = BAD_CAST "(null)";
+
     /* not all libraries handle printing null pointers nicely */
     if (publicId == NULL)
         publicId = nullstr;
@@ -841,8 +884,8 @@
         systemId = nullstr;
     if (content == NULL)
         content = (xmlChar *)nullstr;
-    callbacks++;
-    if (noout)
+    lint->callbacks++;
+    if (lint->noout)
 	return;
     fprintf(stdout, "SAX.entityDecl(%s, %d, %s, %s, %s)\n",
             name, type, publicId, systemId, content);
@@ -857,12 +900,14 @@
  * An attribute definition has been parsed
  */
 static void
-attributeDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar * elem,
+attributeDeclDebug(void *ctx, const xmlChar * elem,
                    const xmlChar * name, int type, int def,
                    const xmlChar * defaultValue, xmlEnumerationPtr tree)
 {
-    callbacks++;
-    if (noout)
+    xmllintState *lint = ctx;
+
+    lint->callbacks++;
+    if (lint->noout)
         return;
     if (defaultValue == NULL)
         fprintf(stdout, "SAX.attributeDecl(%s, %s, %d, %d, NULL, ...)\n",
@@ -883,11 +928,13 @@
  * An element definition has been parsed
  */
 static void
-elementDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, int type,
+elementDeclDebug(void *ctx, const xmlChar *name, int type,
 	    xmlElementContentPtr content ATTRIBUTE_UNUSED)
 {
-    callbacks++;
-    if (noout)
+    xmllintState *lint = ctx;
+
+    lint->callbacks++;
+    if (lint->noout)
 	return;
     fprintf(stdout, "SAX.elementDecl(%s, %d, ...)\n",
             name, type);
@@ -903,11 +950,13 @@
  * What to do when a notation declaration has been parsed.
  */
 static void
-notationDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
+notationDeclDebug(void *ctx, const xmlChar *name,
 	     const xmlChar *publicId, const xmlChar *systemId)
 {
-    callbacks++;
-    if (noout)
+    xmllintState *lint = ctx;
+
+    lint->callbacks++;
+    if (lint->noout)
 	return;
     fprintf(stdout, "SAX.notationDecl(%s, %s, %s)\n",
             (char *) name, (char *) publicId, (char *) systemId);
@@ -924,11 +973,12 @@
  * What to do when an unparsed entity declaration is parsed
  */
 static void
-unparsedEntityDeclDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
+unparsedEntityDeclDebug(void *ctx, const xmlChar *name,
 		   const xmlChar *publicId, const xmlChar *systemId,
 		   const xmlChar *notationName)
 {
-const xmlChar *nullstr = BAD_CAST "(null)";
+    xmllintState *lint = ctx;
+    const xmlChar *nullstr = BAD_CAST "(null)";
 
     if (publicId == NULL)
         publicId = nullstr;
@@ -936,8 +986,8 @@
         systemId = nullstr;
     if (notationName == NULL)
         notationName = nullstr;
-    callbacks++;
-    if (noout)
+    lint->callbacks++;
+    if (lint->noout)
 	return;
     fprintf(stdout, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
             (char *) name, (char *) publicId, (char *) systemId,
@@ -953,10 +1003,12 @@
  * Everything is available on the context, so this is useless in our case.
  */
 static void
-setDocumentLocatorDebug(void *ctx ATTRIBUTE_UNUSED, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
+setDocumentLocatorDebug(void *ctx, xmlSAXLocatorPtr loc ATTRIBUTE_UNUSED)
 {
-    callbacks++;
-    if (noout)
+    xmllintState *lint = ctx;
+
+    lint->callbacks++;
+    if (lint->noout)
 	return;
     fprintf(stdout, "SAX.setDocumentLocator()\n");
 }
@@ -968,10 +1020,12 @@
  * called when the document start being processed.
  */
 static void
-startDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
+startDocumentDebug(void *ctx)
 {
-    callbacks++;
-    if (noout)
+    xmllintState *lint = ctx;
+
+    lint->callbacks++;
+    if (lint->noout)
 	return;
     fprintf(stdout, "SAX.startDocument()\n");
 }
@@ -983,14 +1037,17 @@
  * called when the document end has been detected.
  */
 static void
-endDocumentDebug(void *ctx ATTRIBUTE_UNUSED)
+endDocumentDebug(void *ctx)
 {
-    callbacks++;
-    if (noout)
+    xmllintState *lint = ctx;
+
+    lint->callbacks++;
+    if (lint->noout)
 	return;
     fprintf(stdout, "SAX.endDocument()\n");
 }
 
+#ifdef LIBXML_SAX1_ENABLED
 /**
  * startElementDebug:
  * @ctxt:  An XML parser context
@@ -999,12 +1056,13 @@
  * called when an opening tag has been processed.
  */
 static void
-startElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name, const xmlChar **atts)
+startElementDebug(void *ctx, const xmlChar *name, const xmlChar **atts)
 {
+    xmllintState *lint = ctx;
     int i;
 
-    callbacks++;
-    if (noout)
+    lint->callbacks++;
+    if (lint->noout)
 	return;
     fprintf(stdout, "SAX.startElement(%s", (char *) name);
     if (atts != NULL) {
@@ -1025,13 +1083,16 @@
  * called when the end of an element has been detected.
  */
 static void
-endElementDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
+endElementDebug(void *ctx, const xmlChar *name)
 {
-    callbacks++;
-    if (noout)
+    xmllintState *lint = ctx;
+
+    lint->callbacks++;
+    if (lint->noout)
 	return;
     fprintf(stdout, "SAX.endElement(%s)\n", (char *) name);
 }
+#endif /* LIBXML_SAX1_ENABLED */
 
 /**
  * charactersDebug:
@@ -1043,13 +1104,14 @@
  * Question: how much at a time ???
  */
 static void
-charactersDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
+charactersDebug(void *ctx, const xmlChar *ch, int len)
 {
+    xmllintState *lint = ctx;
     char out[40];
     int i;
 
-    callbacks++;
-    if (noout)
+    lint->callbacks++;
+    if (lint->noout)
 	return;
     for (i = 0;(i<len) && (i < 30);i++)
 	out[i] = (char) ch[i];
@@ -1066,10 +1128,12 @@
  * called when an entity reference is detected.
  */
 static void
-referenceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name)
+referenceDebug(void *ctx, const xmlChar *name)
 {
-    callbacks++;
-    if (noout)
+    xmllintState *lint = ctx;
+
+    lint->callbacks++;
+    if (lint->noout)
 	return;
     fprintf(stdout, "SAX.reference(%s)\n", name);
 }
@@ -1085,13 +1149,14 @@
  * Question: how much at a time ???
  */
 static void
-ignorableWhitespaceDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *ch, int len)
+ignorableWhitespaceDebug(void *ctx, const xmlChar *ch, int len)
 {
+    xmllintState *lint = ctx;
     char out[40];
     int i;
 
-    callbacks++;
-    if (noout)
+    lint->callbacks++;
+    if (lint->noout)
 	return;
     for (i = 0;(i<len) && (i < 30);i++)
 	out[i] = ch[i];
@@ -1109,11 +1174,13 @@
  * A processing instruction has been parsed.
  */
 static void
-processingInstructionDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *target,
+processingInstructionDebug(void *ctx, const xmlChar *target,
                       const xmlChar *data)
 {
-    callbacks++;
-    if (noout)
+    xmllintState *lint = ctx;
+
+    lint->callbacks++;
+    if (lint->noout)
 	return;
     if (data != NULL)
 	fprintf(stdout, "SAX.processingInstruction(%s, %s)\n",
@@ -1132,10 +1199,12 @@
  * called when a pcdata block has been parsed
  */
 static void
-cdataBlockDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
+cdataBlockDebug(void *ctx, const xmlChar *value, int len)
 {
-    callbacks++;
-    if (noout)
+    xmllintState *lint = ctx;
+
+    lint->callbacks++;
+    if (lint->noout)
 	return;
     fprintf(stdout, "SAX.pcdata(%.20s, %d)\n",
 	    (char *) value, len);
@@ -1149,10 +1218,12 @@
  * A comment has been parsed.
  */
 static void
-commentDebug(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
+commentDebug(void *ctx, const xmlChar *value)
 {
-    callbacks++;
-    if (noout)
+    xmllintState *lint = ctx;
+
+    lint->callbacks++;
+    if (lint->noout)
 	return;
     fprintf(stdout, "SAX.comment(%s)\n", value);
 }
@@ -1167,12 +1238,13 @@
  * extra parameters.
  */
 static void LIBXML_ATTR_FORMAT(2,3)
-warningDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
+warningDebug(void *ctx, const char *msg, ...)
 {
+    xmllintState *lint = ctx;
     va_list args;
 
-    callbacks++;
-    if (noout)
+    lint->callbacks++;
+    if (lint->noout)
 	return;
     va_start(args, msg);
     fprintf(stdout, "SAX.warning: ");
@@ -1190,12 +1262,13 @@
  * extra parameters.
  */
 static void LIBXML_ATTR_FORMAT(2,3)
-errorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
+errorDebug(void *ctx, const char *msg, ...)
 {
+    xmllintState *lint = ctx;
     va_list args;
 
-    callbacks++;
-    if (noout)
+    lint->callbacks++;
+    if (lint->noout)
 	return;
     va_start(args, msg);
     fprintf(stdout, "SAX.error: ");
@@ -1213,12 +1286,13 @@
  * extra parameters.
  */
 static void LIBXML_ATTR_FORMAT(2,3)
-fatalErrorDebug(void *ctx ATTRIBUTE_UNUSED, const char *msg, ...)
+fatalErrorDebug(void *ctx, const char *msg, ...)
 {
+    xmllintState *lint = ctx;
     va_list args;
 
-    callbacks++;
-    if (noout)
+    lint->callbacks++;
+    if (lint->noout)
 	return;
     va_start(args, msg);
     fprintf(stdout, "SAX.fatalError: ");
@@ -1226,7 +1300,8 @@
     va_end(args);
 }
 
-static xmlSAXHandler debugSAXHandlerStruct = {
+#ifdef LIBXML_SAX1_ENABLED
+static const xmlSAXHandler debugSAXHandler = {
     internalSubsetDebug,
     isStandaloneDebug,
     hasInternalSubsetDebug,
@@ -1260,8 +1335,7 @@
     NULL,
     NULL
 };
-
-xmlSAXHandlerPtr debugSAXHandler = &debugSAXHandlerStruct;
+#endif
 
 /*
  * SAX2 specific callbacks
@@ -1274,7 +1348,7 @@
  * called when an opening tag has been processed.
  */
 static void
-startElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
+startElementNsDebug(void *ctx,
                     const xmlChar *localname,
                     const xmlChar *prefix,
                     const xmlChar *URI,
@@ -1284,10 +1358,11 @@
 		    int nb_defaulted,
 		    const xmlChar **attributes)
 {
+    xmllintState *lint = ctx;
     int i;
 
-    callbacks++;
-    if (noout)
+    lint->callbacks++;
+    if (lint->noout)
 	return;
     fprintf(stdout, "SAX.startElementNs(%s", (char *) localname);
     if (prefix == NULL)
@@ -1331,13 +1406,15 @@
  * called when the end of an element has been detected.
  */
 static void
-endElementNsDebug(void *ctx ATTRIBUTE_UNUSED,
+endElementNsDebug(void *ctx,
                   const xmlChar *localname,
                   const xmlChar *prefix,
                   const xmlChar *URI)
 {
-    callbacks++;
-    if (noout)
+    xmllintState *lint = ctx;
+
+    lint->callbacks++;
+    if (lint->noout)
 	return;
     fprintf(stdout, "SAX.endElementNs(%s", (char *) localname);
     if (prefix == NULL)
@@ -1350,7 +1427,7 @@
 	fprintf(stdout, ", '%s')\n", (char *) URI);
 }
 
-static xmlSAXHandler debugSAX2HandlerStruct = {
+static const xmlSAXHandler debugSAX2Handler = {
     internalSubsetDebug,
     isStandaloneDebug,
     hasInternalSubsetDebug,
@@ -1385,27 +1462,24 @@
     NULL
 };
 
-static xmlSAXHandlerPtr debugSAX2Handler = &debugSAX2HandlerStruct;
-
 static void
-testSAX(const char *filename) {
-    xmlSAXHandlerPtr handler;
-    const char *user_data = "user_data"; /* mostly for debugging */
+testSAX(xmllintState *lint, const char *filename) {
+    const xmlSAXHandler *handler;
 
-    callbacks = 0;
+    lint->callbacks = 0;
 
-    if (noout) {
-        handler = emptySAXHandler;
+    if (lint->noout) {
+        handler = &emptySAXHandler;
 #ifdef LIBXML_SAX1_ENABLED
-    } else if (options & XML_PARSE_SAX1) {
-        handler = debugSAXHandler;
+    } else if (lint->options & XML_PARSE_SAX1) {
+        handler = &debugSAXHandler;
 #endif
     } else {
-        handler = debugSAX2Handler;
+        handler = &debugSAX2Handler;
     }
 
 #ifdef LIBXML_SCHEMAS_ENABLED
-    if (wxschemas != NULL) {
+    if (lint->wxschemas != NULL) {
         int ret;
 	xmlSchemaValidCtxtPtr vctxt;
         xmlParserInputBufferPtr buf;
@@ -1419,44 +1493,43 @@
         if (buf == NULL)
             return;
 
-	vctxt = xmlSchemaNewValidCtxt(wxschemas);
+	vctxt = xmlSchemaNewValidCtxt(lint->wxschemas);
         if (vctxt == NULL) {
-            progresult = XMLLINT_ERR_MEM;
+            lint->progresult = XMLLINT_ERR_MEM;
             xmlFreeParserInputBuffer(buf);
             return;
         }
 	xmlSchemaValidateSetFilename(vctxt, filename);
 
-	ret = xmlSchemaValidateStream(vctxt, buf, 0, handler,
-	                              (void *)user_data);
-	if (repeat == 1) {
+	ret = xmlSchemaValidateStream(vctxt, buf, 0, handler, lint);
+	if (lint->repeat == 1) {
 	    if (ret == 0) {
-	        if (!quiet) {
+	        if (!lint->quiet) {
 	            fprintf(ERR_STREAM, "%s validates\n", filename);
 	        }
 	    } else if (ret > 0) {
 		fprintf(ERR_STREAM, "%s fails to validate\n", filename);
-		progresult = XMLLINT_ERR_VALID;
+		lint->progresult = XMLLINT_ERR_VALID;
 	    } else {
 		fprintf(ERR_STREAM, "%s validation generated an internal error\n",
 		       filename);
-		progresult = XMLLINT_ERR_VALID;
+		lint->progresult = XMLLINT_ERR_VALID;
 	    }
 	}
 	xmlSchemaFreeValidCtxt(vctxt);
     } else
 #endif
 #ifdef LIBXML_HTML_ENABLED
-    if (html) {
+    if (lint->html) {
         htmlParserCtxtPtr ctxt = NULL;
 
-	ctxt = htmlNewSAXParserCtxt(handler, (void *) user_data);
+	ctxt = htmlNewSAXParserCtxt(handler, lint);
 	if (ctxt == NULL) {
-            progresult = XMLLINT_ERR_MEM;
+            lint->progresult = XMLLINT_ERR_MEM;
 	    return;
 	}
 
-        parseHtml(ctxt, filename);
+        parseHtml(lint, filename);
 
         htmlFreeParserCtxt(ctxt);
     } else
@@ -1464,13 +1537,13 @@
     {
         xmlParserCtxtPtr ctxt = NULL;
 
-	ctxt = xmlNewSAXParserCtxt(handler, (void *) user_data);
+	ctxt = xmlNewSAXParserCtxt(handler, lint);
 	if (ctxt == NULL) {
-            progresult = XMLLINT_ERR_MEM;
+            lint->progresult = XMLLINT_ERR_MEM;
 	    return;
 	}
 
-        parseXml(ctxt, filename);
+        parseXml(lint, filename);
 
 	if (ctxt->myDoc != NULL) {
 	    fprintf(ERR_STREAM, "SAX generated a doc !\n");
@@ -1487,14 +1560,14 @@
  *									*
  ************************************************************************/
 #ifdef LIBXML_READER_ENABLED
-static void processNode(xmlTextReaderPtr reader) {
+static void processNode(xmllintState *lint, xmlTextReaderPtr reader) {
     const xmlChar *name, *value;
     int type, empty;
 
     type = xmlTextReaderNodeType(reader);
     empty = xmlTextReaderIsEmptyElement(reader);
 
-    if (debug) {
+    if (lint->debug) {
 	name = xmlTextReaderConstName(reader);
 	if (name == NULL)
 	    name = BAD_CAST "--";
@@ -1515,30 +1588,31 @@
 	}
     }
 #ifdef LIBXML_PATTERN_ENABLED
-    if (patternc) {
+    if (lint->patternc) {
         xmlChar *path = NULL;
         int match = -1;
 
 	if (type == XML_READER_TYPE_ELEMENT) {
 	    /* do the check only on element start */
-	    match = xmlPatternMatch(patternc, xmlTextReaderCurrentNode(reader));
+	    match = xmlPatternMatch(lint->patternc,
+                                    xmlTextReaderCurrentNode(reader));
 
 	    if (match) {
 		path = xmlGetNodePath(xmlTextReaderCurrentNode(reader));
-		printf("Node %s matches pattern %s\n", path, pattern);
+		printf("Node %s matches pattern %s\n", path, lint->pattern);
 	    }
 	}
-	if (patstream != NULL) {
+	if (lint->patstream != NULL) {
 	    int ret;
 
 	    if (type == XML_READER_TYPE_ELEMENT) {
-		ret = xmlStreamPush(patstream,
+		ret = xmlStreamPush(lint->patstream,
 		                    xmlTextReaderConstLocalName(reader),
 				    xmlTextReaderConstNamespaceUri(reader));
 		if (ret < 0) {
 		    fprintf(ERR_STREAM, "xmlStreamPush() failure\n");
-                    xmlFreeStreamCtxt(patstream);
-		    patstream = NULL;
+                    xmlFreeStreamCtxt(lint->patstream);
+		    lint->patstream = NULL;
 		} else if (ret != match) {
 		    if (path == NULL) {
 		        path = xmlGetNodePath(
@@ -1548,20 +1622,20 @@
 		            "xmlPatternMatch and xmlStreamPush disagree\n");
                     if (path != NULL)
                         fprintf(ERR_STREAM, "  pattern %s node %s\n",
-                                pattern, path);
+                                lint->pattern, path);
                     else
 		        fprintf(ERR_STREAM, "  pattern %s node %s\n",
-			    pattern, xmlTextReaderConstName(reader));
+			    lint->pattern, xmlTextReaderConstName(reader));
 		}
 
 	    }
 	    if ((type == XML_READER_TYPE_END_ELEMENT) ||
 	        ((type == XML_READER_TYPE_ELEMENT) && (empty))) {
-	        ret = xmlStreamPop(patstream);
+	        ret = xmlStreamPop(lint->patstream);
 		if (ret < 0) {
 		    fprintf(ERR_STREAM, "xmlStreamPop() failure\n");
-                    xmlFreeStreamCtxt(patstream);
-		    patstream = NULL;
+                    xmlFreeStreamCtxt(lint->patstream);
+		    lint->patstream = NULL;
 		}
 	    }
 	}
@@ -1571,28 +1645,28 @@
 #endif
 }
 
-static void streamFile(const char *filename) {
+static void streamFile(xmllintState *lint, const char *filename) {
     xmlTextReaderPtr reader;
     int ret;
 #if HAVE_DECL_MMAP
-    if (memory) {
-	reader = xmlReaderForMemory(memoryData, memorySize, filename,
-	                            NULL, options);
+    if (lint->memory) {
+	reader = xmlReaderForMemory(lint->memoryData, lint->memorySize,
+                                    filename, NULL, lint->options);
     } else
 #endif
     if (strcmp(filename, "-") == 0)
-	reader = xmlReaderForFd(STDIN_FILENO, "-", NULL, options);
+	reader = xmlReaderForFd(STDIN_FILENO, "-", NULL, lint->options);
     else
-	reader = xmlReaderForFile(filename, NULL, options);
+	reader = xmlReaderForFile(filename, NULL, lint->options);
 #ifdef LIBXML_PATTERN_ENABLED
-    if (patternc != NULL) {
-        patstream = xmlPatternGetStreamCtxt(patternc);
-	if (patstream != NULL) {
-	    ret = xmlStreamPush(patstream, NULL, NULL);
+    if (lint->patternc != NULL) {
+        lint->patstream = xmlPatternGetStreamCtxt(lint->patternc);
+	if (lint->patstream != NULL) {
+	    ret = xmlStreamPush(lint->patstream, NULL, NULL);
 	    if (ret < 0) {
 		fprintf(ERR_STREAM, "xmlStreamPush() failure\n");
-		xmlFreeStreamCtxt(patstream);
-		patstream = NULL;
+		xmlFreeStreamCtxt(lint->patstream);
+		lint->patstream = NULL;
             }
 	}
     }
@@ -1600,39 +1674,39 @@
 
 
     if (reader != NULL) {
-        xmlTextReaderSetResourceLoader(reader, xmllintResourceLoader, NULL);
-        if (maxAmpl > 0)
-            xmlTextReaderSetMaxAmplification(reader, maxAmpl);
+        xmlTextReaderSetResourceLoader(reader, xmllintResourceLoader, lint);
+        if (lint->maxAmpl > 0)
+            xmlTextReaderSetMaxAmplification(reader, lint->maxAmpl);
 
 #ifdef LIBXML_SCHEMAS_ENABLED
-	if (relaxng != NULL) {
-	    if ((timing) && (repeat == 1)) {
-		startTimer();
+	if (lint->relaxng != NULL) {
+	    if ((lint->timing) && (lint->repeat == 1)) {
+		startTimer(lint);
 	    }
-	    ret = xmlTextReaderRelaxNGValidate(reader, relaxng);
+	    ret = xmlTextReaderRelaxNGValidate(reader, lint->relaxng);
 	    if (ret < 0) {
-		fprintf(ERR_STREAM,
-			"Relax-NG schema %s failed to compile\n", relaxng);
-		progresult = XMLLINT_ERR_SCHEMACOMP;
-		relaxng = NULL;
+		fprintf(ERR_STREAM, "Relax-NG schema %s failed to compile\n",
+                        lint->relaxng);
+		lint->progresult = XMLLINT_ERR_SCHEMACOMP;
+		lint->relaxng = NULL;
 	    }
-	    if ((timing) && (repeat == 1)) {
-		endTimer("Compiling the schemas");
+	    if ((lint->timing) && (lint->repeat == 1)) {
+		endTimer(lint, "Compiling the schemas");
 	    }
 	}
-	if (schema != NULL) {
-	    if ((timing) && (repeat == 1)) {
-		startTimer();
+	if (lint->schema != NULL) {
+	    if ((lint->timing) && (lint->repeat == 1)) {
+		startTimer(lint);
 	    }
-	    ret = xmlTextReaderSchemaValidate(reader, schema);
+	    ret = xmlTextReaderSchemaValidate(reader, lint->schema);
 	    if (ret < 0) {
-		fprintf(ERR_STREAM,
-			"XSD schema %s failed to compile\n", schema);
-		progresult = XMLLINT_ERR_SCHEMACOMP;
-		schema = NULL;
+		fprintf(ERR_STREAM, "XSD schema %s failed to compile\n",
+                        lint->schema);
+		lint->progresult = XMLLINT_ERR_SCHEMACOMP;
+		lint->schema = NULL;
 	    }
-	    if ((timing) && (repeat == 1)) {
-		endTimer("Compiling the schemas");
+	    if ((lint->timing) && (lint->repeat == 1)) {
+		endTimer(lint, "Compiling the schemas");
 	    }
 	}
 #endif
@@ -1640,49 +1714,49 @@
 	/*
 	 * Process all nodes in sequence
 	 */
-	if ((timing) && (repeat == 1)) {
-	    startTimer();
+	if ((lint->timing) && (lint->repeat == 1)) {
+	    startTimer(lint);
 	}
 	ret = xmlTextReaderRead(reader);
 	while (ret == 1) {
-	    if ((debug)
+	    if ((lint->debug)
 #ifdef LIBXML_PATTERN_ENABLED
-	        || (patternc)
+	        || (lint->patternc)
 #endif
 	       )
-		processNode(reader);
+		processNode(lint, reader);
 	    ret = xmlTextReaderRead(reader);
 	}
-	if ((timing) && (repeat == 1)) {
+	if ((lint->timing) && (lint->repeat == 1)) {
 #ifdef LIBXML_SCHEMAS_ENABLED
-	    if (relaxng != NULL)
-		endTimer("Parsing and validating");
+	    if (lint->relaxng != NULL)
+		endTimer(lint, "Parsing and validating");
 	    else
 #endif
 #ifdef LIBXML_VALID_ENABLED
-	    if (options & XML_PARSE_DTDVALID)
-		endTimer("Parsing and validating");
+	    if (lint->options & XML_PARSE_DTDVALID)
+		endTimer(lint, "Parsing and validating");
 	    else
 #endif
-	    endTimer("Parsing");
+	    endTimer(lint, "Parsing");
 	}
 
 #ifdef LIBXML_VALID_ENABLED
-	if (options & XML_PARSE_DTDVALID) {
+	if (lint->options & XML_PARSE_DTDVALID) {
 	    if (xmlTextReaderIsValid(reader) != 1) {
 		fprintf(ERR_STREAM,
 			"Document %s does not validate\n", filename);
-		progresult = XMLLINT_ERR_VALID;
+		lint->progresult = XMLLINT_ERR_VALID;
 	    }
 	}
 #endif /* LIBXML_VALID_ENABLED */
 #ifdef LIBXML_SCHEMAS_ENABLED
-	if ((relaxng != NULL) || (schema != NULL)) {
+	if ((lint->relaxng != NULL) || (lint->schema != NULL)) {
 	    if (xmlTextReaderIsValid(reader) != 1) {
 		fprintf(ERR_STREAM, "%s fails to validate\n", filename);
-		progresult = XMLLINT_ERR_VALID;
+		lint->progresult = XMLLINT_ERR_VALID;
 	    } else {
-	        if (!quiet) {
+	        if (!lint->quiet) {
 	            fprintf(ERR_STREAM, "%s validates\n", filename);
 	        }
 	    }
@@ -1694,26 +1768,26 @@
 	xmlFreeTextReader(reader);
 	if (ret != 0) {
 	    fprintf(ERR_STREAM, "%s : failed to parse\n", filename);
-	    progresult = XMLLINT_ERR_UNCLASS;
+	    lint->progresult = XMLLINT_ERR_UNCLASS;
 	}
     } else {
 	fprintf(ERR_STREAM, "Unable to open %s\n", filename);
-	progresult = XMLLINT_ERR_UNCLASS;
+	lint->progresult = XMLLINT_ERR_UNCLASS;
     }
 #ifdef LIBXML_PATTERN_ENABLED
-    if (patstream != NULL) {
-	xmlFreeStreamCtxt(patstream);
-	patstream = NULL;
+    if (lint->patstream != NULL) {
+	xmlFreeStreamCtxt(lint->patstream);
+	lint->patstream = NULL;
     }
 #endif
 }
 
-static void walkDoc(xmlDocPtr doc) {
+static void walkDoc(xmllintState *lint, xmlDocPtr doc) {
     xmlTextReaderPtr reader;
     int ret;
 
 #ifdef LIBXML_PATTERN_ENABLED
-    if (pattern != NULL) {
+    if (lint->pattern != NULL) {
         xmlNodePtr root;
         const xmlChar *namespaces[22];
         int i;
@@ -1723,7 +1797,7 @@
         if (root == NULL ) {
             fprintf(ERR_STREAM,
                     "Document does not have a root element");
-            progresult = XMLLINT_ERR_UNCLASS;
+            lint->progresult = XMLLINT_ERR_UNCLASS;
             return;
         }
         for (ns = root->nsDef, i = 0;ns != NULL && i < 20;ns=ns->next) {
@@ -1733,70 +1807,70 @@
         namespaces[i++] = NULL;
         namespaces[i] = NULL;
 
-        ret = xmlPatternCompileSafe((const xmlChar *) pattern, doc->dict,
-                                    0, &namespaces[0], &patternc);
-	if (patternc == NULL) {
+        ret = xmlPatternCompileSafe((const xmlChar *) lint->pattern, doc->dict,
+                                    0, &namespaces[0], &lint->patternc);
+	if (lint->patternc == NULL) {
             if (ret < 0) {
-                progresult = XMLLINT_ERR_MEM;
+                lint->progresult = XMLLINT_ERR_MEM;
             } else {
-                fprintf(ERR_STREAM,
-                        "Pattern %s failed to compile\n", pattern);
-                progresult = XMLLINT_ERR_SCHEMAPAT;
+                fprintf(ERR_STREAM, "Pattern %s failed to compile\n",
+                        lint->pattern);
+                lint->progresult = XMLLINT_ERR_SCHEMAPAT;
             }
             goto error;
 	}
 
-        patstream = xmlPatternGetStreamCtxt(patternc);
-        if (patstream == NULL) {
-            progresult = XMLLINT_ERR_MEM;
+        lint->patstream = xmlPatternGetStreamCtxt(lint->patternc);
+        if (lint->patstream == NULL) {
+            lint->progresult = XMLLINT_ERR_MEM;
             goto error;
         }
 
-        ret = xmlStreamPush(patstream, NULL, NULL);
+        ret = xmlStreamPush(lint->patstream, NULL, NULL);
         if (ret < 0) {
             fprintf(ERR_STREAM, "xmlStreamPush() failure\n");
-            progresult = XMLLINT_ERR_MEM;
+            lint->progresult = XMLLINT_ERR_MEM;
             goto error;
         }
     }
 #endif /* LIBXML_PATTERN_ENABLED */
     reader = xmlReaderWalker(doc);
     if (reader != NULL) {
-	if ((timing) && (repeat == 1)) {
-	    startTimer();
+	if ((lint->timing) && (lint->repeat == 1)) {
+	    startTimer(lint);
 	}
 	ret = xmlTextReaderRead(reader);
 	while (ret == 1) {
-	    if ((debug)
+	    if ((lint->debug)
 #ifdef LIBXML_PATTERN_ENABLED
-	        || (patternc)
+	        || (lint->patternc)
 #endif
 	       )
-		processNode(reader);
+		processNode(lint, reader);
 	    ret = xmlTextReaderRead(reader);
 	}
-	if ((timing) && (repeat == 1)) {
-	    endTimer("walking through the doc");
+	if ((lint->timing) && (lint->repeat == 1)) {
+	    endTimer(lint, "walking through the doc");
 	}
 	xmlFreeTextReader(reader);
 	if (ret != 0) {
 	    fprintf(ERR_STREAM, "failed to walk through the doc\n");
-	    progresult = XMLLINT_ERR_UNCLASS;
+	    lint->progresult = XMLLINT_ERR_UNCLASS;
 	}
     } else {
 	fprintf(ERR_STREAM, "Failed to crate a reader from the document\n");
-	progresult = XMLLINT_ERR_UNCLASS;
+	lint->progresult = XMLLINT_ERR_UNCLASS;
     }
 
 #ifdef LIBXML_PATTERN_ENABLED
 error:
-    if (patternc != NULL) {
-        xmlFreePattern(patternc);
-        patternc = NULL;
+    if (lint->patternc != NULL) {
+        xmlFreePattern(lint->patternc);
+        lint->patternc = NULL;
     }
-    if (patstream != NULL) {
-	xmlFreeStreamCtxt(patstream);
-	patstream = NULL;
+    if (lint->patstream != NULL) {
+	xmlFreeStreamCtxt(lint->patstream);
+	lint->patstream = NULL;
     }
 #endif
 }
@@ -1809,7 +1883,8 @@
  *									*
  ************************************************************************/
 
-static void doXPathDump(xmlXPathObjectPtr cur) {
+static void
+doXPathDump(xmllintState *lint, xmlXPathObjectPtr cur) {
     switch(cur->type) {
         case XPATH_NODESET: {
 #ifdef LIBXML_OUTPUT_ENABLED
@@ -1818,8 +1893,8 @@
             int i;
 
             if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr <= 0)) {
-                progresult = XMLLINT_ERR_XPATH_EMPTY;
-                if (!quiet) {
+                lint->progresult = XMLLINT_ERR_XPATH_EMPTY;
+                if (!lint->quiet) {
                     fprintf(ERR_STREAM, "XPath set is empty\n");
                 }
                 break;
@@ -1827,7 +1902,7 @@
             buf = xmlOutputBufferCreateFile(stdout, NULL);
             if (buf == NULL) {
                 fprintf(ERR_STREAM, "Out of memory for XPath\n");
-                progresult = XMLLINT_ERR_MEM;
+                lint->progresult = XMLLINT_ERR_MEM;
                 return;
             }
             for (i = 0;i < cur->nodesetval->nodeNr;i++) {
@@ -1866,16 +1941,17 @@
 	    break;
         case XPATH_UNDEFINED:
 	    fprintf(ERR_STREAM, "XPath Object is uninitialized\n");
-            progresult = XMLLINT_ERR_XPATH;
+            lint->progresult = XMLLINT_ERR_XPATH;
 	    break;
 	default:
 	    fprintf(ERR_STREAM, "XPath object of unexpected type\n");
-            progresult = XMLLINT_ERR_XPATH;
+            lint->progresult = XMLLINT_ERR_XPATH;
 	    break;
     }
 }
 
-static void doXPathQuery(xmlDocPtr doc, const char *query) {
+static void
+doXPathQuery(xmllintState *lint, xmlDocPtr doc, const char *query) {
     xmlXPathContextPtr ctxt = NULL;
     xmlXPathCompExprPtr comp = NULL;
     xmlXPathObjectPtr res = NULL;
@@ -1883,19 +1959,19 @@
     ctxt = xmlXPathNewContext(doc);
     if (ctxt == NULL) {
         fprintf(ERR_STREAM, "Out of memory for XPath\n");
-        progresult = XMLLINT_ERR_MEM;
+        lint->progresult = XMLLINT_ERR_MEM;
         goto error;
     }
 
     comp = xmlXPathCtxtCompile(ctxt, BAD_CAST query);
     if (comp == NULL) {
         fprintf(ERR_STREAM, "XPath compilation failure\n");
-        progresult = XMLLINT_ERR_XPATH;
+        lint->progresult = XMLLINT_ERR_XPATH;
         goto error;
     }
 
 #ifdef LIBXML_DEBUG_ENABLED
-    if (debug) {
+    if (lint->debug) {
         xmlXPathDebugDumpCompExpr(stdout, comp, 0);
         printf("\n");
     }
@@ -1905,11 +1981,11 @@
     res = xmlXPathCompiledEval(comp, ctxt);
     if (res == NULL) {
         fprintf(ERR_STREAM, "XPath evaluation failure\n");
-        progresult = XMLLINT_ERR_XPATH;
+        lint->progresult = XMLLINT_ERR_XPATH;
         goto error;
     }
 
-    doXPathDump(res);
+    doXPathDump(lint, res);
 
 error:
     xmlXPathFreeObject(res);
@@ -1925,31 +2001,31 @@
  ************************************************************************/
 
 static xmlDocPtr
-parseFile(const char *filename, xmlParserCtxtPtr ctxt) {
+parseFile(xmllintState *lint, const char *filename) {
     xmlDocPtr doc = NULL;
     int errNo;
 #ifdef LIBXML_VALID_ENABLED
     int valid;
 #endif
 
-    if ((generate) && (filename == NULL)) {
+    if ((lint->generate) && (filename == NULL)) {
         xmlNodePtr n;
 
         doc = xmlNewDoc(BAD_CAST "1.0");
         if (doc == NULL) {
-            progresult = XMLLINT_ERR_MEM;
+            lint->progresult = XMLLINT_ERR_MEM;
             return(NULL);
         }
         n = xmlNewDocNode(doc, NULL, BAD_CAST "info", NULL);
         if (n == NULL) {
             xmlFreeDoc(doc);
-            progresult = XMLLINT_ERR_MEM;
+            lint->progresult = XMLLINT_ERR_MEM;
             return(NULL);
         }
         if (xmlNodeSetContent(n, BAD_CAST "abc") < 0) {
             xmlFreeNode(n);
             xmlFreeDoc(doc);
-            progresult = XMLLINT_ERR_MEM;
+            lint->progresult = XMLLINT_ERR_MEM;
             return(NULL);
         }
         xmlDocSetRootElement(doc, n);
@@ -1959,7 +2035,8 @@
 
 #ifdef LIBXML_HTML_ENABLED
 #ifdef LIBXML_PUSH_ENABLED
-    if ((html) && (push)) {
+    if ((lint->html) && (lint->push)) {
+        htmlParserCtxtPtr ctxt;
         FILE *f;
         int res;
         char chars[4096];
@@ -1970,7 +2047,7 @@
 	    f = fopen(filename, "rb");
             if (f == NULL) {
                 fprintf(ERR_STREAM, "Can't open %s\n", filename);
-                progresult = XMLLINT_ERR_RDFILE;
+                lint->progresult = XMLLINT_ERR_RDFILE;
                 return(NULL);
             }
         }
@@ -1979,13 +2056,13 @@
         ctxt = htmlCreatePushParserCtxt(NULL, NULL,
                     chars, res, filename, XML_CHAR_ENCODING_NONE);
         if (ctxt == NULL) {
-            progresult = XMLLINT_ERR_MEM;
+            lint->progresult = XMLLINT_ERR_MEM;
             if (f != stdin)
                 fclose(f);
             return(NULL);
         }
-        htmlCtxtUseOptions(ctxt, options);
-        while ((res = fread(chars, 1, pushsize, f)) > 0) {
+        htmlCtxtUseOptions(ctxt, lint->options);
+        while ((res = fread(chars, 1, lint->pushsize, f)) > 0) {
             htmlParseChunk(ctxt, chars, res, 0);
         }
         htmlParseChunk(ctxt, chars, 0, 1);
@@ -1998,14 +2075,15 @@
     }
 #endif /* LIBXML_PUSH_ENABLED */
 
-    if (html) {
-        doc = parseHtml(ctxt, filename);
+    if (lint->html) {
+        doc = parseHtml(lint, filename);
         return(doc);
     }
 #endif /* LIBXML_HTML_ENABLED */
 
 #ifdef LIBXML_PUSH_ENABLED
-    if (push) {
+    if (lint->push) {
+        xmlParserCtxtPtr ctxt;
         FILE *f;
         int res;
         char chars[4096];
@@ -2016,30 +2094,31 @@
             f = fopen(filename, "rb");
             if (f == NULL) {
                 fprintf(ERR_STREAM, "Can't open %s\n", filename);
-                progresult = XMLLINT_ERR_RDFILE;
+                lint->progresult = XMLLINT_ERR_RDFILE;
                 return(NULL);
             }
         }
 
         res = fread(chars, 1, 4, f);
-        ctxt = xmlCreatePushParserCtxt(NULL, NULL,
-                    chars, res, filename);
+        ctxt = xmlCreatePushParserCtxt(NULL, NULL, chars, res, filename);
         if (ctxt == NULL) {
-            progresult = XMLLINT_ERR_MEM;
+            lint->progresult = XMLLINT_ERR_MEM;
             if (f != stdin)
                 fclose(f);
             return(NULL);
         }
 
-        xmlCtxtSetResourceLoader(ctxt, xmllintResourceLoader, NULL);
-        xmlCtxtUseOptions(ctxt, options);
-        if (maxAmpl > 0)
-            xmlCtxtSetMaxAmplification(ctxt, maxAmpl);
+        xmlCtxtSetResourceLoader(ctxt, xmllintResourceLoader, lint);
+        xmlCtxtUseOptions(ctxt, lint->options);
+        if (lint->maxAmpl > 0)
+            xmlCtxtSetMaxAmplification(ctxt, lint->maxAmpl);
 
-        if (htmlout)
+        if (lint->htmlout) {
+            ctxt->_private = lint;
             xmlCtxtSetErrorHandler(ctxt, xmlHTMLError, ctxt);
+        }
 
-        while ((res = fread(chars, 1, pushsize, f)) > 0) {
+        while ((res = fread(chars, 1, lint->pushsize, f)) > 0) {
             xmlParseChunk(ctxt, chars, res, 0);
         }
         xmlParseChunk(ctxt, chars, 0, 1);
@@ -2055,25 +2134,27 @@
     } else
 #endif /* LIBXML_PUSH_ENABLED */
     {
-        doc = parseXml(ctxt, filename);
-        errNo = ctxt->errNo;
-#ifdef LIBXML_VALID_ENABLED
-        valid = ctxt->valid;
-#endif
+        if (lint->htmlout) {
+            lint->ctxt->_private = lint;
+            xmlCtxtSetErrorHandler(lint->ctxt, xmlHTMLError, lint->ctxt);
+        }
 
-        if (htmlout)
-            xmlCtxtSetErrorHandler(ctxt, xmlHTMLError, ctxt);
+        doc = parseXml(lint, filename);
+        errNo = lint->ctxt->errNo;
+#ifdef LIBXML_VALID_ENABLED
+        valid = lint->ctxt->valid;
+#endif
     }
 
     if (doc == NULL) {
         if (errNo == XML_ERR_NO_MEMORY)
-            progresult = XMLLINT_ERR_MEM;
+            lint->progresult = XMLLINT_ERR_MEM;
         else
-	    progresult = XMLLINT_ERR_RDFILE;
+	    lint->progresult = XMLLINT_ERR_RDFILE;
     } else {
 #ifdef LIBXML_VALID_ENABLED
-        if ((options & XML_PARSE_DTDVALID) && (valid == 0))
-            progresult = XMLLINT_ERR_VALID;
+        if ((lint->options & XML_PARSE_DTDVALID) && (valid == 0))
+            lint->progresult = XMLLINT_ERR_VALID;
 #endif /* LIBXML_VALID_ENABLED */
     }
 
@@ -2081,24 +2162,24 @@
 }
 
 static void
-parseAndPrintFile(const char *filename, xmlParserCtxtPtr pctxt) {
+parseAndPrintFile(xmllintState *lint, const char *filename) {
     xmlDocPtr doc;
 
-    if ((timing) && (repeat == 1))
-	startTimer();
+    if ((lint->timing) && (lint->repeat == 1))
+	startTimer(lint);
 
-    doc = parseFile(filename, pctxt);
+    doc = parseFile(lint, filename);
     if (doc == NULL) {
-        if (progresult == XMLLINT_RETURN_OK)
-            progresult = XMLLINT_ERR_UNCLASS;
+        if (lint->progresult == XMLLINT_RETURN_OK)
+            lint->progresult = XMLLINT_ERR_UNCLASS;
 	return;
     }
 
-    if ((timing) && (repeat == 1)) {
-	endTimer("Parsing");
+    if ((lint->timing) && (lint->repeat == 1)) {
+	endTimer(lint, "Parsing");
     }
 
-    if (dropdtd) {
+    if (lint->dropdtd) {
 	xmlDtdPtr dtd;
 
 	dtd = xmlGetIntSubset(doc);
@@ -2109,14 +2190,16 @@
     }
 
 #ifdef LIBXML_XINCLUDE_ENABLED
-    if (xinclude) {
-	if ((timing) && (repeat == 1)) {
-	    startTimer();
+    if (lint->xinclude) {
+	if ((lint->timing) && (lint->repeat == 1)) {
+	    startTimer(lint);
 	}
-	if (xmlXIncludeProcessFlags(doc, options) < 0)
-	    progresult = XMLLINT_ERR_UNCLASS;
-	if ((timing) && (repeat == 1)) {
-	    endTimer("Xinclude processing");
+	if (xmlXIncludeProcessFlags(doc, lint->options) < 0) {
+	    lint->progresult = XMLLINT_ERR_UNCLASS;
+            return;
+        }
+	if ((lint->timing) && (lint->repeat == 1)) {
+	    endTimer(lint, "Xinclude processing");
 	}
     }
 #endif
@@ -2125,7 +2208,7 @@
     /*
      * shell interaction
      */
-    if (shell) {
+    if (lint->shell) {
 #ifdef LIBXML_XPATH_ENABLED
         xmlXPathOrderDocElems(doc);
 #endif
@@ -2135,44 +2218,44 @@
 #endif
 
 #ifdef LIBXML_XPATH_ENABLED
-    if (xpathquery != NULL) {
+    if (lint->xpathquery != NULL) {
 	xmlXPathOrderDocElems(doc);
-        doXPathQuery(doc, xpathquery);
+        doXPathQuery(lint, doc, lint->xpathquery);
     }
 #endif
 
     /*
      * test intermediate copy if needed.
      */
-    if (copy) {
+    if (lint->copy) {
         xmlDocPtr tmp;
 
         tmp = doc;
-	if (timing) {
-	    startTimer();
+	if (lint->timing) {
+	    startTimer(lint);
 	}
 	doc = xmlCopyDoc(doc, 1);
         if (doc == NULL) {
-            progresult = XMLLINT_ERR_MEM;
+            lint->progresult = XMLLINT_ERR_MEM;
             xmlFreeDoc(tmp);
             return;
         }
-	if (timing) {
-	    endTimer("Copying");
+	if (lint->timing) {
+	    endTimer(lint, "Copying");
 	}
-	if (timing) {
-	    startTimer();
+	if (lint->timing) {
+	    startTimer(lint);
 	}
 	xmlFreeDoc(tmp);
-	if (timing) {
-	    endTimer("Freeing original");
+	if (lint->timing) {
+	    endTimer(lint, "Freeing original");
 	}
     }
 
 #ifdef LIBXML_VALID_ENABLED
-    if ((insert)
+    if ((lint->insert)
 #ifdef LIBXML_HTML_ENABLED
-        && (!html)
+        && (!lint->html)
 #endif
     ) {
         const xmlChar* list[256];
@@ -2200,68 +2283,72 @@
 		}
 	    }
 	}
-    }else
+    } else
 #endif /* LIBXML_VALID_ENABLED */
 #ifdef LIBXML_READER_ENABLED
-    if (walker) {
-        walkDoc(doc);
+    if (lint->walker) {
+        walkDoc(lint, doc);
     }
 #endif /* LIBXML_READER_ENABLED */
 #ifdef LIBXML_OUTPUT_ENABLED
-    if (noout == 0) {
-        if (compress)
+    if (lint->noout == 0) {
+        if (lint->compress)
             xmlSetDocCompressMode(doc, 9);
 
 	/*
 	 * print it.
 	 */
 #ifdef LIBXML_DEBUG_ENABLED
-	if (!debug) {
+	if (!lint->debug) {
 #endif
-	    if ((timing) && (repeat == 1)) {
-		startTimer();
+	    if ((lint->timing) && (lint->repeat == 1)) {
+		startTimer(lint);
 	    }
 #ifdef LIBXML_HTML_ENABLED
-            if ((html) && (!xmlout)) {
-		if (compress) {
-		    htmlSaveFile(output ? output : "-", doc);
+            if ((lint->html) && (!lint->xmlout)) {
+		if (lint->compress) {
+		    htmlSaveFile(lint->output ? lint->output : "-", doc);
 		}
-		else if (encoding != NULL) {
-		    if (format == 1) {
-			htmlSaveFileFormat(output ? output : "-", doc, encoding, 1);
+		else if (lint->encoding != NULL) {
+		    if (lint->format == 1) {
+			htmlSaveFileFormat(lint->output ? lint->output : "-",
+                                           doc, lint->encoding, 1);
 		    }
 		    else {
-			htmlSaveFileFormat(output ? output : "-", doc, encoding, 0);
+			htmlSaveFileFormat(lint->output ? lint->output : "-",
+                                           doc, lint->encoding, 0);
 		    }
 		}
-		else if (format == 1) {
-		    htmlSaveFileFormat(output ? output : "-", doc, NULL, 1);
+		else if (lint->format == 1) {
+		    htmlSaveFileFormat(lint->output ? lint->output : "-",
+                                       doc, NULL, 1);
 		}
 		else {
 		    FILE *out;
-		    if (output == NULL)
+		    if (lint->output == NULL)
 			out = stdout;
 		    else {
-			out = fopen(output,"wb");
+			out = fopen(lint->output,"wb");
 		    }
 		    if (out != NULL) {
 			if (htmlDocDump(out, doc) < 0)
-			    progresult = XMLLINT_ERR_OUT;
+			    lint->progresult = XMLLINT_ERR_OUT;
 
-			if (output != NULL)
+			if (lint->output != NULL)
 			    fclose(out);
 		    } else {
-			fprintf(ERR_STREAM, "failed to open %s\n", output);
-			progresult = XMLLINT_ERR_OUT;
+			fprintf(ERR_STREAM, "failed to open %s\n",
+                                lint->output);
+			lint->progresult = XMLLINT_ERR_OUT;
 		    }
 		}
-		if ((timing) && (repeat == 1)) {
-		    endTimer("Saving");
+		if ((lint->timing) && (lint->repeat == 1)) {
+		    endTimer(lint, "Saving");
 		}
 	    } else
 #endif
 #ifdef LIBXML_C14N_ENABLED
-            if (canonical) {
+            if (lint->canonical) {
 	        xmlChar *result = NULL;
 		int size;
 
@@ -2273,9 +2360,9 @@
 		    xmlFree(result);
 		} else {
 		    fprintf(ERR_STREAM, "Failed to canonicalize\n");
-		    progresult = XMLLINT_ERR_OUT;
+		    lint->progresult = XMLLINT_ERR_OUT;
 		}
-	    } else if (canonical_11) {
+	    } else if (lint->canonical_11) {
 	        xmlChar *result = NULL;
 		int size;
 
@@ -2287,10 +2374,9 @@
 		    xmlFree(result);
 		} else {
 		    fprintf(ERR_STREAM, "Failed to canonicalize\n");
-		    progresult = XMLLINT_ERR_OUT;
+		    lint->progresult = XMLLINT_ERR_OUT;
 		}
-	    } else
-            if (exc_canonical) {
+	    } else if (lint->exc_canonical) {
 	        xmlChar *result = NULL;
 		int size;
 
@@ -2302,30 +2388,32 @@
 		    xmlFree(result);
 		} else {
 		    fprintf(ERR_STREAM, "Failed to canonicalize\n");
-		    progresult = XMLLINT_ERR_OUT;
+		    lint->progresult = XMLLINT_ERR_OUT;
 		}
 	    } else
 #endif
 #if HAVE_DECL_MMAP
-	    if (memory) {
+	    if (lint->memory) {
 		xmlChar *result;
 		int len;
 
-		if (encoding != NULL) {
-		    if (format == 1) {
-		        xmlDocDumpFormatMemoryEnc(doc, &result, &len, encoding, 1);
+		if (lint->encoding != NULL) {
+		    if (lint->format == 1) {
+		        xmlDocDumpFormatMemoryEnc(doc, &result, &len,
+                                                  lint->encoding, 1);
 		    } else {
-			xmlDocDumpMemoryEnc(doc, &result, &len, encoding);
+			xmlDocDumpMemoryEnc(doc, &result, &len,
+                                            lint->encoding);
 		    }
 		} else {
-		    if (format == 1)
+		    if (lint->format == 1)
 			xmlDocDumpFormatMemory(doc, &result, &len, 1);
 		    else
 			xmlDocDumpMemory(doc, &result, &len);
 		}
 		if (result == NULL) {
 		    fprintf(ERR_STREAM, "Failed to save\n");
-		    progresult = XMLLINT_ERR_OUT;
+		    lint->progresult = XMLLINT_ERR_OUT;
 		} else {
 		    if (write(1, result, len) == -1) {
 		        fprintf(ERR_STREAM, "Can't write data\n");
@@ -2335,57 +2423,59 @@
 
 	    } else
 #endif /* HAVE_DECL_MMAP */
-	    if (compress) {
-		xmlSaveFile(output ? output : "-", doc);
+	    if (lint->compress) {
+		xmlSaveFile(lint->output ? lint->output : "-", doc);
 	    } else {
 	        xmlSaveCtxtPtr ctxt;
 		int saveOpts = 0;
 
-                if (format == 1)
+                if (lint->format == 1)
 		    saveOpts |= XML_SAVE_FORMAT;
-                else if (format == 2)
+                else if (lint->format == 2)
                     saveOpts |= XML_SAVE_WSNONSIG;
 
 #if defined(LIBXML_HTML_ENABLED)
-                if (xmlout)
+                if (lint->xmlout)
                     saveOpts |= XML_SAVE_AS_XML;
 #endif
 
-		if (output == NULL)
-		    ctxt = xmlSaveToFd(1, encoding, saveOpts);
+		if (lint->output == NULL)
+		    ctxt = xmlSaveToFd(STDOUT_FILENO, lint->encoding,
+                                       saveOpts);
 		else
-		    ctxt = xmlSaveToFilename(output, encoding, saveOpts);
+		    ctxt = xmlSaveToFilename(lint->output, lint->encoding,
+                                             saveOpts);
 
 		if (ctxt != NULL) {
 		    if (xmlSaveDoc(ctxt, doc) < 0) {
 			fprintf(ERR_STREAM, "failed save to %s\n",
-				output ? output : "-");
-			progresult = XMLLINT_ERR_OUT;
+				lint->output ? lint->output : "-");
+			lint->progresult = XMLLINT_ERR_OUT;
 		    }
 		    xmlSaveClose(ctxt);
 		} else {
-		    progresult = XMLLINT_ERR_OUT;
+		    lint->progresult = XMLLINT_ERR_OUT;
 		}
 	    }
-	    if ((timing) && (repeat == 1)) {
-		endTimer("Saving");
+	    if ((lint->timing) && (lint->repeat == 1)) {
+		endTimer(lint, "Saving");
 	    }
 #ifdef LIBXML_DEBUG_ENABLED
 	} else {
 	    FILE *out;
-	    if (output == NULL)
+	    if (lint->output == NULL)
 	        out = stdout;
 	    else {
-		out = fopen(output,"wb");
+		out = fopen(lint->output, "wb");
 	    }
 	    if (out != NULL) {
 		xmlDebugDumpDocument(out, doc);
 
-		if (output != NULL)
+		if (lint->output != NULL)
 		    fclose(out);
 	    } else {
-		fprintf(ERR_STREAM, "failed to open %s\n", output);
-		progresult = XMLLINT_ERR_OUT;
+		fprintf(ERR_STREAM, "failed to open %s\n", lint->output);
+		lint->progresult = XMLLINT_ERR_OUT;
 	    }
 	}
 #endif
@@ -2396,27 +2486,27 @@
     /*
      * A posteriori validation test
      */
-    if ((dtdvalid != NULL) || (dtdvalidfpi != NULL)) {
+    if ((lint->dtdvalid != NULL) || (lint->dtdvalidfpi != NULL)) {
 	xmlDtdPtr dtd;
 
-	if ((timing) && (repeat == 1)) {
-	    startTimer();
+	if ((lint->timing) && (lint->repeat == 1)) {
+	    startTimer(lint);
 	}
-	if (dtdvalid != NULL)
-	    dtd = xmlParseDTD(NULL, (const xmlChar *)dtdvalid);
+	if (lint->dtdvalid != NULL)
+	    dtd = xmlParseDTD(NULL, BAD_CAST lint->dtdvalid);
 	else
-	    dtd = xmlParseDTD((const xmlChar *)dtdvalidfpi, NULL);
-	if ((timing) && (repeat == 1)) {
-	    endTimer("Parsing DTD");
+	    dtd = xmlParseDTD(BAD_CAST lint->dtdvalidfpi, NULL);
+	if ((lint->timing) && (lint->repeat == 1)) {
+	    endTimer(lint, "Parsing DTD");
 	}
 	if (dtd == NULL) {
-	    if (dtdvalid != NULL)
-		fprintf(ERR_STREAM,
-			"Could not parse DTD %s\n", dtdvalid);
+	    if (lint->dtdvalid != NULL)
+		fprintf(ERR_STREAM, "Could not parse DTD %s\n",
+                        lint->dtdvalid);
 	    else
-		fprintf(ERR_STREAM,
-			"Could not parse DTD %s\n", dtdvalidfpi);
-	    progresult = XMLLINT_ERR_DTD;
+		fprintf(ERR_STREAM, "Could not parse DTD %s\n",
+                        lint->dtdvalidfpi);
+	    lint->progresult = XMLLINT_ERR_DTD;
 	} else {
 	    xmlValidCtxtPtr cvp;
 
@@ -2424,168 +2514,168 @@
 	    if (cvp == NULL) {
 		fprintf(ERR_STREAM,
 			"Couldn't allocate validation context\n");
-                progresult = XMLLINT_ERR_MEM;
+                lint->progresult = XMLLINT_ERR_MEM;
                 xmlFreeDtd(dtd);
                 return;
 	    }
 
-	    if ((timing) && (repeat == 1)) {
-		startTimer();
+	    if ((lint->timing) && (lint->repeat == 1)) {
+		startTimer(lint);
 	    }
 	    if (!xmlValidateDtd(cvp, doc, dtd)) {
-		if (dtdvalid != NULL)
+		if (lint->dtdvalid != NULL)
 		    fprintf(ERR_STREAM,
 			    "Document %s does not validate against %s\n",
-			    filename, dtdvalid);
+			    filename, lint->dtdvalid);
 		else
 		    fprintf(ERR_STREAM,
 			    "Document %s does not validate against %s\n",
-			    filename, dtdvalidfpi);
-		progresult = XMLLINT_ERR_VALID;
+			    filename, lint->dtdvalidfpi);
+		lint->progresult = XMLLINT_ERR_VALID;
 	    }
-	    if ((timing) && (repeat == 1)) {
-		endTimer("Validating against DTD");
+	    if ((lint->timing) && (lint->repeat == 1)) {
+		endTimer(lint, "Validating against DTD");
 	    }
 	    xmlFreeValidCtxt(cvp);
 	    xmlFreeDtd(dtd);
 	}
-    } else if (postvalid) {
+    } else if (lint->postvalid) {
 	xmlValidCtxtPtr cvp;
 
 	cvp = xmlNewValidCtxt();
 	if (cvp == NULL) {
 	    fprintf(ERR_STREAM,
 		    "Couldn't allocate validation context\n");
-            progresult = XMLLINT_ERR_MEM;
+            lint->progresult = XMLLINT_ERR_MEM;
             xmlFreeDoc(doc);
             return;
 	}
 
-	if ((timing) && (repeat == 1)) {
-	    startTimer();
+	if ((lint->timing) && (lint->repeat == 1)) {
+	    startTimer(lint);
 	}
 	if (!xmlValidateDocument(cvp, doc)) {
 	    fprintf(ERR_STREAM,
 		    "Document %s does not validate\n", filename);
-	    progresult = XMLLINT_ERR_VALID;
+	    lint->progresult = XMLLINT_ERR_VALID;
 	}
-	if ((timing) && (repeat == 1)) {
-	    endTimer("Validating");
+	if ((lint->timing) && (lint->repeat == 1)) {
+	    endTimer(lint, "Validating");
 	}
 	xmlFreeValidCtxt(cvp);
     }
 #endif /* LIBXML_VALID_ENABLED */
 #ifdef LIBXML_SCHEMATRON_ENABLED
-    if (wxschematron != NULL) {
+    if (lint->wxschematron != NULL) {
 	xmlSchematronValidCtxtPtr ctxt;
 	int ret;
 	int flag;
 
-	if ((timing) && (repeat == 1)) {
-	    startTimer();
+	if ((lint->timing) && (lint->repeat == 1)) {
+	    startTimer(lint);
 	}
 
-	if (debug)
+	if (lint->debug)
 	    flag = XML_SCHEMATRON_OUT_XML;
 	else
 	    flag = XML_SCHEMATRON_OUT_TEXT;
-	if (noout)
+	if (lint->noout)
 	    flag |= XML_SCHEMATRON_OUT_QUIET;
-	ctxt = xmlSchematronNewValidCtxt(wxschematron, flag);
+	ctxt = xmlSchematronNewValidCtxt(lint->wxschematron, flag);
         if (ctxt == NULL) {
-            progresult = XMLLINT_ERR_MEM;
+            lint->progresult = XMLLINT_ERR_MEM;
             xmlFreeDoc(doc);
             return;
         }
 	ret = xmlSchematronValidateDoc(ctxt, doc);
 	if (ret == 0) {
-	    if (!quiet) {
+	    if (!lint->quiet) {
 	        fprintf(ERR_STREAM, "%s validates\n", filename);
 	    }
 	} else if (ret > 0) {
 	    fprintf(ERR_STREAM, "%s fails to validate\n", filename);
-	    progresult = XMLLINT_ERR_VALID;
+	    lint->progresult = XMLLINT_ERR_VALID;
 	} else {
 	    fprintf(ERR_STREAM, "%s validation generated an internal error\n",
 		   filename);
-	    progresult = XMLLINT_ERR_VALID;
+	    lint->progresult = XMLLINT_ERR_VALID;
 	}
 	xmlSchematronFreeValidCtxt(ctxt);
-	if ((timing) && (repeat == 1)) {
-	    endTimer("Validating");
+	if ((lint->timing) && (lint->repeat == 1)) {
+	    endTimer(lint, "Validating");
 	}
     }
 #endif
 #ifdef LIBXML_SCHEMAS_ENABLED
-    if (relaxngschemas != NULL) {
+    if (lint->relaxngschemas != NULL) {
 	xmlRelaxNGValidCtxtPtr ctxt;
 	int ret;
 
-	if ((timing) && (repeat == 1)) {
-	    startTimer();
+	if ((lint->timing) && (lint->repeat == 1)) {
+	    startTimer(lint);
 	}
 
-	ctxt = xmlRelaxNGNewValidCtxt(relaxngschemas);
+	ctxt = xmlRelaxNGNewValidCtxt(lint->relaxngschemas);
         if (ctxt == NULL) {
-            progresult = XMLLINT_ERR_MEM;
+            lint->progresult = XMLLINT_ERR_MEM;
             xmlFreeDoc(doc);
             return;
         }
 	ret = xmlRelaxNGValidateDoc(ctxt, doc);
 	if (ret == 0) {
-	    if (!quiet) {
+	    if (!lint->quiet) {
 	        fprintf(ERR_STREAM, "%s validates\n", filename);
 	    }
 	} else if (ret > 0) {
 	    fprintf(ERR_STREAM, "%s fails to validate\n", filename);
-	    progresult = XMLLINT_ERR_VALID;
+	    lint->progresult = XMLLINT_ERR_VALID;
 	} else {
 	    fprintf(ERR_STREAM, "%s validation generated an internal error\n",
 		   filename);
-	    progresult = XMLLINT_ERR_VALID;
+	    lint->progresult = XMLLINT_ERR_VALID;
 	}
 	xmlRelaxNGFreeValidCtxt(ctxt);
-	if ((timing) && (repeat == 1)) {
-	    endTimer("Validating");
+	if ((lint->timing) && (lint->repeat == 1)) {
+	    endTimer(lint, "Validating");
 	}
-    } else if (wxschemas != NULL) {
+    } else if (lint->wxschemas != NULL) {
 	xmlSchemaValidCtxtPtr ctxt;
 	int ret;
 
-	if ((timing) && (repeat == 1)) {
-	    startTimer();
+	if ((lint->timing) && (lint->repeat == 1)) {
+	    startTimer(lint);
 	}
 
-	ctxt = xmlSchemaNewValidCtxt(wxschemas);
+	ctxt = xmlSchemaNewValidCtxt(lint->wxschemas);
         if (ctxt == NULL) {
-            progresult = XMLLINT_ERR_MEM;
+            lint->progresult = XMLLINT_ERR_MEM;
             xmlFreeDoc(doc);
             return;
         }
 	ret = xmlSchemaValidateDoc(ctxt, doc);
 	if (ret == 0) {
-	    if (!quiet) {
+	    if (!lint->quiet) {
 	        fprintf(ERR_STREAM, "%s validates\n", filename);
 	    }
 	} else if (ret > 0) {
 	    fprintf(ERR_STREAM, "%s fails to validate\n", filename);
-	    progresult = XMLLINT_ERR_VALID;
+	    lint->progresult = XMLLINT_ERR_VALID;
 	} else {
 	    fprintf(ERR_STREAM, "%s validation generated an internal error\n",
 		   filename);
-	    progresult = XMLLINT_ERR_VALID;
+	    lint->progresult = XMLLINT_ERR_VALID;
 	}
 	xmlSchemaFreeValidCtxt(ctxt);
-	if ((timing) && (repeat == 1)) {
-	    endTimer("Validating");
+	if ((lint->timing) && (lint->repeat == 1)) {
+	    endTimer(lint, "Validating");
 	}
     }
 #endif
 
 #ifdef LIBXML_DEBUG_ENABLED
-    if ((debugent)
+    if ((lint->debugent)
 #if defined(LIBXML_HTML_ENABLED)
-        && (!html)
+        && (!lint->html)
 #endif
     )
 	xmlDebugDumpEntities(ERR_STREAM, doc);
@@ -2598,12 +2688,12 @@
     /*
      * free it.
      */
-    if ((timing) && (repeat == 1)) {
-	startTimer();
+    if ((lint->timing) && (lint->repeat == 1)) {
+	startTimer(lint);
     }
     xmlFreeDoc(doc);
-    if ((timing) && (repeat == 1)) {
-	endTimer("Freeing");
+    if ((lint->timing) && (lint->repeat == 1)) {
+	endTimer(lint, "Freeing");
     }
 }
 
@@ -2835,96 +2925,320 @@
     return(0);
 }
 
+static void
+xmllintInit(xmllintState *lint) {
+    memset(lint, 0, sizeof(*lint));
+
+    lint->repeat = 1;
+    lint->progresult = XMLLINT_RETURN_OK;
+    lint->options = XML_PARSE_COMPACT | XML_PARSE_BIG_LINES;
+}
+
 static int
-xmllintMain(int argc, const char **argv, xmlResourceLoader loader) {
-    int i, j;
-    int files = 0;
-    int version = 0;
-    int nowrap = 0;
-    int sax = 0;
-#ifdef LIBXML_READER_ENABLED
-    int stream = 0;
-#endif
-#ifdef LIBXML_CATALOG_ENABLED
-    int catalogs = 0;
-    int nocatalogs = 0;
-#endif
+xmllintParseOptions(xmllintState *lint, int argc, const char **argv) {
+    int i;
 
-    defaultResourceLoader = loader;
+    if (argc <= 1) {
+        usage(ERR_STREAM, argv[0]);
+        return(XMLLINT_ERR_UNCLASS);
+    }
 
-#ifdef XMLLINT_FUZZ
-#ifdef LIBXML_DEBUG_ENABLED
-    shell = 0;
-    debugent = 0;
-#endif
-    debug = 0;
-    maxmem = 0;
-    copy = 0;
-    noout = 0;
-#ifdef LIBXML_OUTPUT_ENABLED
-    format = 0;
-    output = NULL;
-    compress = 0;
-#endif /* LIBXML_OUTPUT_ENABLED */
+    for (i = 1; i < argc ; i++) {
+        if (argv[i][0] != '-' || argv[i][1] == 0)
+            continue;
+
+        if ((!strcmp(argv[i], "-maxmem")) ||
+            (!strcmp(argv[i], "--maxmem"))) {
+            i++;
+            if (i >= argc) {
+                fprintf(ERR_STREAM, "maxmem: missing integer value\n");
+                return(XMLLINT_ERR_UNCLASS);
+            }
+            errno = 0;
+            xmllintMaxmem = parseInteger("maxmem", argv[i], 0, INT_MAX);
+        } else if ((!strcmp(argv[i], "-debug")) ||
+                   (!strcmp(argv[i], "--debug"))) {
+            lint->debug = 1;
+        } else if ((!strcmp(argv[i], "-shell")) ||
+                   (!strcmp(argv[i], "--shell"))) {
+            lint->shell = 1;
+        } else if ((!strcmp(argv[i], "-copy")) ||
+                   (!strcmp(argv[i], "--copy"))) {
+            lint->copy = 1;
+        } else if ((!strcmp(argv[i], "-recover")) ||
+                   (!strcmp(argv[i], "--recover"))) {
+            lint->options |= XML_PARSE_RECOVER;
+        } else if ((!strcmp(argv[i], "-huge")) ||
+                   (!strcmp(argv[i], "--huge"))) {
+            lint->options |= XML_PARSE_HUGE;
+        } else if ((!strcmp(argv[i], "-noent")) ||
+                   (!strcmp(argv[i], "--noent"))) {
+            lint->options |= XML_PARSE_NOENT;
+        } else if ((!strcmp(argv[i], "-noenc")) ||
+                   (!strcmp(argv[i], "--noenc"))) {
+            lint->options |= XML_PARSE_IGNORE_ENC;
+        } else if ((!strcmp(argv[i], "-nsclean")) ||
+                   (!strcmp(argv[i], "--nsclean"))) {
+            lint->options |= XML_PARSE_NSCLEAN;
+        } else if ((!strcmp(argv[i], "-nocdata")) ||
+                   (!strcmp(argv[i], "--nocdata"))) {
+            lint->options |= XML_PARSE_NOCDATA;
+        } else if ((!strcmp(argv[i], "-nodict")) ||
+                   (!strcmp(argv[i], "--nodict"))) {
+            lint->options |= XML_PARSE_NODICT;
+        } else if ((!strcmp(argv[i], "-version")) ||
+                   (!strcmp(argv[i], "--version"))) {
+            showVersion(argv[0]);
+            lint->version = 1;
+        } else if ((!strcmp(argv[i], "-noout")) ||
+                   (!strcmp(argv[i], "--noout"))) {
+            lint->noout = 1;
+        } else if ((!strcmp(argv[i], "-htmlout")) ||
+                   (!strcmp(argv[i], "--htmlout"))) {
+            lint->htmlout = 1;
+        } else if ((!strcmp(argv[i], "-nowrap")) ||
+                   (!strcmp(argv[i], "--nowrap"))) {
+            lint->nowrap = 1;
+#ifdef LIBXML_HTML_ENABLED
+        } else if ((!strcmp(argv[i], "-html")) ||
+                   (!strcmp(argv[i], "--html"))) {
+            lint->html = 1;
+        } else if ((!strcmp(argv[i], "-xmlout")) ||
+                   (!strcmp(argv[i], "--xmlout"))) {
+            lint->xmlout = 1;
+        } else if ((!strcmp(argv[i], "-nodefdtd")) ||
+                   (!strcmp(argv[i], "--nodefdtd"))) {
+            lint->options |= HTML_PARSE_NODEFDTD;
+#endif /* LIBXML_HTML_ENABLED */
+        } else if ((!strcmp(argv[i], "-loaddtd")) ||
+                   (!strcmp(argv[i], "--loaddtd"))) {
+            lint->options |= XML_PARSE_DTDLOAD;
+        } else if ((!strcmp(argv[i], "-dtdattr")) ||
+                   (!strcmp(argv[i], "--dtdattr"))) {
+            lint->options |= XML_PARSE_DTDATTR;
 #ifdef LIBXML_VALID_ENABLED
-    postvalid = 0;
-    dtdvalid = NULL;
-    dtdvalidfpi = NULL;
-    insert = 0;
-#endif
-#ifdef LIBXML_SCHEMAS_ENABLED
-    relaxng = NULL;
-    relaxngschemas = NULL;
-    schema = NULL;
-    wxschemas = NULL;
-#endif
-#ifdef LIBXML_SCHEMATRON_ENABLED
-    schematron = NULL;
-    wxschematron = NULL;
-#endif
-    repeat = 1;
-#if defined(LIBXML_HTML_ENABLED)
-    html = 0;
-    xmlout = 0;
-#endif
-    htmlout = 0;
+        } else if ((!strcmp(argv[i], "-valid")) ||
+                   (!strcmp(argv[i], "--valid"))) {
+            lint->options |= XML_PARSE_DTDVALID;
+        } else if ((!strcmp(argv[i], "-postvalid")) ||
+                   (!strcmp(argv[i], "--postvalid"))) {
+            lint->postvalid = 1;
+            lint->options |= XML_PARSE_DTDLOAD;
+        } else if ((!strcmp(argv[i], "-dtdvalid")) ||
+                   (!strcmp(argv[i], "--dtdvalid"))) {
+            i++;
+            lint->dtdvalid = argv[i];
+            lint->options |= XML_PARSE_DTDLOAD;
+        } else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
+                   (!strcmp(argv[i], "--dtdvalidfpi"))) {
+            i++;
+            lint->dtdvalidfpi = argv[i];
+            lint->options |= XML_PARSE_DTDLOAD;
+        } else if ((!strcmp(argv[i], "-insert")) ||
+                   (!strcmp(argv[i], "--insert"))) {
+            lint->insert = 1;
+#endif /* LIBXML_VALID_ENABLED */
+        } else if ((!strcmp(argv[i], "-dropdtd")) ||
+                   (!strcmp(argv[i], "--dropdtd"))) {
+            lint->dropdtd = 1;
+        } else if ((!strcmp(argv[i], "-quiet")) ||
+                   (!strcmp(argv[i], "--quiet"))) {
+            lint->quiet = 1;
+        } else if ((!strcmp(argv[i], "-timing")) ||
+                   (!strcmp(argv[i], "--timing"))) {
+            lint->timing = 1;
+        } else if ((!strcmp(argv[i], "-auto")) ||
+                   (!strcmp(argv[i], "--auto"))) {
+            lint->generate = 1;
+        } else if ((!strcmp(argv[i], "-repeat")) ||
+                   (!strcmp(argv[i], "--repeat"))) {
+            if (lint->repeat > 1)
+                lint->repeat *= 10;
+            else
+                lint->repeat = 100;
 #ifdef LIBXML_PUSH_ENABLED
-    push = 0;
+        } else if ((!strcmp(argv[i], "-push")) ||
+                   (!strcmp(argv[i], "--push"))) {
+            lint->push = 1;
 #endif /* LIBXML_PUSH_ENABLED */
 #if HAVE_DECL_MMAP
-    memory = 0;
-    memoryData = NULL;
-    memorySize = 0;
+        } else if ((!strcmp(argv[i], "-memory")) ||
+                   (!strcmp(argv[i], "--memory"))) {
+            lint->memory = 1;
 #endif
-    testIO = 0;
-    encoding = NULL;
+        } else if ((!strcmp(argv[i], "-testIO")) ||
+                   (!strcmp(argv[i], "--testIO"))) {
+            lint->testIO = 1;
 #ifdef LIBXML_XINCLUDE_ENABLED
-    xinclude = 0;
+        } else if ((!strcmp(argv[i], "-xinclude")) ||
+                   (!strcmp(argv[i], "--xinclude"))) {
+            lint->xinclude = 1;
+            lint->options |= XML_PARSE_XINCLUDE;
+        } else if ((!strcmp(argv[i], "-noxincludenode")) ||
+                   (!strcmp(argv[i], "--noxincludenode"))) {
+            lint->xinclude = 1;
+            lint->options |= XML_PARSE_XINCLUDE;
+            lint->options |= XML_PARSE_NOXINCNODE;
+        } else if ((!strcmp(argv[i], "-nofixup-base-uris")) ||
+                   (!strcmp(argv[i], "--nofixup-base-uris"))) {
+            lint->xinclude = 1;
+            lint->options |= XML_PARSE_XINCLUDE;
+            lint->options |= XML_PARSE_NOBASEFIX;
 #endif
-    progresult = XMLLINT_RETURN_OK;
-    quiet = 0;
-    timing = 0;
-    generate = 0;
-    dropdtd = 0;
+        } else if ((!strcmp(argv[i], "-nowarning")) ||
+                   (!strcmp(argv[i], "--nowarning"))) {
+            lint->options |= XML_PARSE_NOWARNING;
+            lint->options &= ~XML_PARSE_PEDANTIC;
+        } else if ((!strcmp(argv[i], "-pedantic")) ||
+                   (!strcmp(argv[i], "--pedantic"))) {
+            lint->options |= XML_PARSE_PEDANTIC;
+            lint->options &= ~XML_PARSE_NOWARNING;
+#ifdef LIBXML_DEBUG_ENABLED
+        } else if ((!strcmp(argv[i], "-debugent")) ||
+                   (!strcmp(argv[i], "--debugent"))) {
+            lint->debugent = 1;
+#endif
 #ifdef LIBXML_C14N_ENABLED
-    canonical = 0;
-    canonical_11 = 0;
-    exc_canonical = 0;
+        } else if ((!strcmp(argv[i], "-c14n")) ||
+                   (!strcmp(argv[i], "--c14n"))) {
+            lint->canonical = 1;
+            lint->options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
+        } else if ((!strcmp(argv[i], "-c14n11")) ||
+                   (!strcmp(argv[i], "--c14n11"))) {
+            lint->canonical_11 = 1;
+            lint->options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
+        } else if ((!strcmp(argv[i], "-exc-c14n")) ||
+                   (!strcmp(argv[i], "--exc-c14n"))) {
+            lint->exc_canonical = 1;
+            lint->options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
 #endif
+#ifdef LIBXML_CATALOG_ENABLED
+        } else if ((!strcmp(argv[i], "-catalogs")) ||
+                   (!strcmp(argv[i], "--catalogs"))) {
+            lint->catalogs = 1;
+        } else if ((!strcmp(argv[i], "-nocatalogs")) ||
+                   (!strcmp(argv[i], "--nocatalogs"))) {
+            lint->nocatalogs = 1;
+#endif
+        } else if ((!strcmp(argv[i], "-noblanks")) ||
+                   (!strcmp(argv[i], "--noblanks"))) {
+            lint->options |= XML_PARSE_NOBLANKS;
+#ifdef LIBXML_OUTPUT_ENABLED
+        } else if ((!strcmp(argv[i], "-o")) ||
+                   (!strcmp(argv[i], "-output")) ||
+                   (!strcmp(argv[i], "--output"))) {
+            i++;
+            lint->output = argv[i];
+        } else if ((!strcmp(argv[i], "-format")) ||
+                   (!strcmp(argv[i], "--format"))) {
+            lint->format = 1;
+            lint->options |= XML_PARSE_NOBLANKS;
+        } else if ((!strcmp(argv[i], "-encode")) ||
+                   (!strcmp(argv[i], "--encode"))) {
+            i++;
+            lint->encoding = argv[i];
+        } else if ((!strcmp(argv[i], "-pretty")) ||
+                   (!strcmp(argv[i], "--pretty"))) {
+            i++;
+            if (argv[i] != NULL)
+                lint->format = atoi(argv[i]);
+#ifdef LIBXML_ZLIB_ENABLED
+        } else if ((!strcmp(argv[i], "-compress")) ||
+                   (!strcmp(argv[i], "--compress"))) {
+            lint->compress = 1;
+#endif
+#endif /* LIBXML_OUTPUT_ENABLED */
 #ifdef LIBXML_READER_ENABLED
-    walker = 0;
+        } else if ((!strcmp(argv[i], "-stream")) ||
+                   (!strcmp(argv[i], "--stream"))) {
+             lint->stream = 1;
+        } else if ((!strcmp(argv[i], "-walker")) ||
+                   (!strcmp(argv[i], "--walker"))) {
+             lint->walker = 1;
+             lint->noout = 1;
 #ifdef LIBXML_PATTERN_ENABLED
-    pattern = NULL;
-    patternc = NULL;
-    patstream = NULL;
+        } else if ((!strcmp(argv[i], "-pattern")) ||
+                   (!strcmp(argv[i], "--pattern"))) {
+            i++;
+            lint->pattern = argv[i];
 #endif
 #endif /* LIBXML_READER_ENABLED */
-#ifdef LIBXML_XPATH_ENABLED
-    xpathquery = NULL;
+#ifdef LIBXML_SAX1_ENABLED
+        } else if ((!strcmp(argv[i], "-sax1")) ||
+                   (!strcmp(argv[i], "--sax1"))) {
+            lint->options |= XML_PARSE_SAX1;
+#endif /* LIBXML_SAX1_ENABLED */
+        } else if ((!strcmp(argv[i], "-sax")) ||
+                   (!strcmp(argv[i], "--sax"))) {
+            lint->sax = 1;
+#ifdef LIBXML_SCHEMAS_ENABLED
+        } else if ((!strcmp(argv[i], "-relaxng")) ||
+                   (!strcmp(argv[i], "--relaxng"))) {
+            i++;
+            lint->relaxng = argv[i];
+            lint->options |= XML_PARSE_NOENT;
+        } else if ((!strcmp(argv[i], "-schema")) ||
+                 (!strcmp(argv[i], "--schema"))) {
+            i++;
+            lint->schema = argv[i];
+            lint->options |= XML_PARSE_NOENT;
 #endif
-    options = XML_PARSE_COMPACT | XML_PARSE_BIG_LINES;
-    maxAmpl = 0;
-#endif /* XMLLINT_FUZZ */
+#ifdef LIBXML_SCHEMATRON_ENABLED
+        } else if ((!strcmp(argv[i], "-schematron")) ||
+                   (!strcmp(argv[i], "--schematron"))) {
+            i++;
+            lint->schematron = argv[i];
+            lint->options |= XML_PARSE_NOENT;
+#endif
+        } else if ((!strcmp(argv[i], "-nonet")) ||
+                   (!strcmp(argv[i], "--nonet"))) {
+            lint->options |= XML_PARSE_NONET;
+        } else if ((!strcmp(argv[i], "-nocompact")) ||
+                   (!strcmp(argv[i], "--nocompact"))) {
+            lint->options &= ~XML_PARSE_COMPACT;
+        } else if ((!strcmp(argv[i], "-load-trace")) ||
+                   (!strcmp(argv[i], "--load-trace"))) {
+            lint->load_trace = 1;
+        } else if ((!strcmp(argv[i], "-path")) ||
+                   (!strcmp(argv[i], "--path"))) {
+            i++;
+            parsePath(lint, BAD_CAST argv[i]);
+#ifdef LIBXML_XPATH_ENABLED
+        } else if ((!strcmp(argv[i], "-xpath")) ||
+                   (!strcmp(argv[i], "--xpath"))) {
+            i++;
+            lint->noout++;
+            lint->xpathquery = argv[i];
+#endif
+        } else if ((!strcmp(argv[i], "-oldxml10")) ||
+                   (!strcmp(argv[i], "--oldxml10"))) {
+            lint->options |= XML_PARSE_OLD10;
+        } else if ((!strcmp(argv[i], "-max-ampl")) ||
+                   (!strcmp(argv[i], "--max-ampl"))) {
+            i++;
+            if (i >= argc) {
+                fprintf(ERR_STREAM, "max-ampl: missing integer value\n");
+                return(XMLLINT_ERR_UNCLASS);
+            }
+            lint->maxAmpl = parseInteger("max-ampl", argv[i], 1, UINT_MAX);
+        } else {
+            fprintf(ERR_STREAM, "Unknown option %s\n", argv[i]);
+            usage(ERR_STREAM, argv[0]);
+            return(XMLLINT_ERR_UNCLASS);
+        }
+    }
+
+    if (lint->shell)
+        lint->repeat = 1;
+
+    return(XMLLINT_RETURN_OK);
+}
+
+static int
+xmllintMain(int argc, const char **argv, xmlResourceLoader loader) {
+    xmllintState state, *lint;
+    int i, j, res;
+    int files = 0;
 
 #ifdef _WIN32
     _setmode(_fileno(stdin), _O_BINARY);
@@ -2932,352 +3246,26 @@
     _setmode(_fileno(stderr), _O_BINARY);
 #endif
 
-    if (argc <= 1) {
-	usage(ERR_STREAM, argv[0]);
-	return(XMLLINT_ERR_UNCLASS);
+    xmllintMaxmem = 0;
+
+    lint = &state;
+    xmllintInit(lint);
+    lint->defaultResourceLoader = loader;
+
+    res = xmllintParseOptions(lint, argc, argv);
+    if (res != XMLLINT_RETURN_OK) {
+        lint->progresult = res;
+        goto error;
     }
 
-    /* xmlMemSetup must be called before initializing the parser. */
-    for (i = 1; i < argc ; i++) {
-	if ((!strcmp(argv[i], "-maxmem")) ||
-	    (!strcmp(argv[i], "--maxmem"))) {
-            i++;
-            if (i >= argc) {
-                fprintf(ERR_STREAM, "maxmem: missing integer value\n");
-                return(XMLLINT_ERR_UNCLASS);
-            }
-            errno = 0;
-            maxmem = parseInteger("maxmem", argv[i], 0, INT_MAX);
-        } else if (argv[i][0] == '-') {
-            i += skipArgs(argv[i]);
-	}
-    }
-    if (maxmem != 0)
+    if (xmllintMaxmem != 0)
         xmlMemSetup(myFreeFunc, myMallocFunc, myReallocFunc, myStrdupFunc);
 
     LIBXML_TEST_VERSION
 
-    for (i = 1; i < argc ; i++) {
-	if (argv[i][0] != '-' || argv[i][1] == 0)
-	    continue;
-
-	if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
-	    debug++;
-	else
-	if ((!strcmp(argv[i], "-shell")) ||
-	         (!strcmp(argv[i], "--shell"))) {
-	    shell++;
-        } else
-	if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
-	    copy++;
-	else
-	if ((!strcmp(argv[i], "-recover")) ||
-	         (!strcmp(argv[i], "--recover"))) {
-	    options |= XML_PARSE_RECOVER;
-	} else if ((!strcmp(argv[i], "-huge")) ||
-	         (!strcmp(argv[i], "--huge"))) {
-	    options |= XML_PARSE_HUGE;
-	} else if ((!strcmp(argv[i], "-noent")) ||
-	         (!strcmp(argv[i], "--noent"))) {
-	    options |= XML_PARSE_NOENT;
-	} else if ((!strcmp(argv[i], "-noenc")) ||
-	         (!strcmp(argv[i], "--noenc"))) {
-	    options |= XML_PARSE_IGNORE_ENC;
-	} else if ((!strcmp(argv[i], "-nsclean")) ||
-	         (!strcmp(argv[i], "--nsclean"))) {
-	    options |= XML_PARSE_NSCLEAN;
-	} else if ((!strcmp(argv[i], "-nocdata")) ||
-	         (!strcmp(argv[i], "--nocdata"))) {
-	    options |= XML_PARSE_NOCDATA;
-	} else if ((!strcmp(argv[i], "-nodict")) ||
-	         (!strcmp(argv[i], "--nodict"))) {
-	    options |= XML_PARSE_NODICT;
-	} else if ((!strcmp(argv[i], "-version")) ||
-	         (!strcmp(argv[i], "--version"))) {
-	    showVersion(argv[0]);
-	    version = 1;
-	} else if ((!strcmp(argv[i], "-noout")) ||
-	         (!strcmp(argv[i], "--noout")))
-	    noout++;
-	else if ((!strcmp(argv[i], "-htmlout")) ||
-	         (!strcmp(argv[i], "--htmlout")))
-	    htmlout++;
-	else if ((!strcmp(argv[i], "-nowrap")) ||
-	         (!strcmp(argv[i], "--nowrap")))
-	    nowrap++;
-#ifdef LIBXML_HTML_ENABLED
-	else if ((!strcmp(argv[i], "-html")) ||
-	         (!strcmp(argv[i], "--html"))) {
-	    html++;
-        }
-	else if ((!strcmp(argv[i], "-xmlout")) ||
-	         (!strcmp(argv[i], "--xmlout"))) {
-	    xmlout++;
-	} else if ((!strcmp(argv[i], "-nodefdtd")) ||
-	         (!strcmp(argv[i], "--nodefdtd"))) {
-	    options |= HTML_PARSE_NODEFDTD;
-        }
-#endif /* LIBXML_HTML_ENABLED */
-	else if ((!strcmp(argv[i], "-loaddtd")) ||
-	         (!strcmp(argv[i], "--loaddtd"))) {
-	    options |= XML_PARSE_DTDLOAD;
-	} else if ((!strcmp(argv[i], "-dtdattr")) ||
-	         (!strcmp(argv[i], "--dtdattr"))) {
-	    options |= XML_PARSE_DTDATTR;
-	}
-#ifdef LIBXML_VALID_ENABLED
-	else if ((!strcmp(argv[i], "-valid")) ||
-	         (!strcmp(argv[i], "--valid"))) {
-	    options |= XML_PARSE_DTDVALID;
-	} else if ((!strcmp(argv[i], "-postvalid")) ||
-	         (!strcmp(argv[i], "--postvalid"))) {
-	    postvalid++;
-	    options |= XML_PARSE_DTDLOAD;
-	} else if ((!strcmp(argv[i], "-dtdvalid")) ||
-	         (!strcmp(argv[i], "--dtdvalid"))) {
-	    i++;
-	    dtdvalid = argv[i];
-	    options |= XML_PARSE_DTDLOAD;
-	} else if ((!strcmp(argv[i], "-dtdvalidfpi")) ||
-	         (!strcmp(argv[i], "--dtdvalidfpi"))) {
-	    i++;
-	    dtdvalidfpi = argv[i];
-	    options |= XML_PARSE_DTDLOAD;
-        }
-	else if ((!strcmp(argv[i], "-insert")) ||
-	         (!strcmp(argv[i], "--insert")))
-	    insert++;
-#endif /* LIBXML_VALID_ENABLED */
-	else if ((!strcmp(argv[i], "-dropdtd")) ||
-	         (!strcmp(argv[i], "--dropdtd")))
-	    dropdtd++;
-	else if ((!strcmp(argv[i], "-quiet")) ||
-	         (!strcmp(argv[i], "--quiet")))
-	    quiet++;
-	else if ((!strcmp(argv[i], "-timing")) ||
-	         (!strcmp(argv[i], "--timing")))
-	    timing++;
-	else if ((!strcmp(argv[i], "-auto")) ||
-	         (!strcmp(argv[i], "--auto")))
-	    generate++;
-	else if ((!strcmp(argv[i], "-repeat")) ||
-	         (!strcmp(argv[i], "--repeat"))) {
-	    if (repeat > 1)
-	        repeat *= 10;
-	    else
-	        repeat = 100;
-	}
-#ifdef LIBXML_PUSH_ENABLED
-	else if ((!strcmp(argv[i], "-push")) ||
-	         (!strcmp(argv[i], "--push")))
-	    push++;
-#endif /* LIBXML_PUSH_ENABLED */
-#if HAVE_DECL_MMAP
-	else if ((!strcmp(argv[i], "-memory")) ||
-	         (!strcmp(argv[i], "--memory")))
-	    memory++;
-#endif
-	else if ((!strcmp(argv[i], "-testIO")) ||
-	         (!strcmp(argv[i], "--testIO")))
-	    testIO++;
-#ifdef LIBXML_XINCLUDE_ENABLED
-	else if ((!strcmp(argv[i], "-xinclude")) ||
-	         (!strcmp(argv[i], "--xinclude"))) {
-	    xinclude++;
-	    options |= XML_PARSE_XINCLUDE;
-	}
-	else if ((!strcmp(argv[i], "-noxincludenode")) ||
-	         (!strcmp(argv[i], "--noxincludenode"))) {
-	    xinclude++;
-	    options |= XML_PARSE_XINCLUDE;
-	    options |= XML_PARSE_NOXINCNODE;
-	}
-	else if ((!strcmp(argv[i], "-nofixup-base-uris")) ||
-	         (!strcmp(argv[i], "--nofixup-base-uris"))) {
-	    xinclude++;
-	    options |= XML_PARSE_XINCLUDE;
-	    options |= XML_PARSE_NOBASEFIX;
-	}
-#endif
-	else if ((!strcmp(argv[i], "-nowarning")) ||
-	         (!strcmp(argv[i], "--nowarning"))) {
-	    options |= XML_PARSE_NOWARNING;
-            options &= ~XML_PARSE_PEDANTIC;
-        }
-	else if ((!strcmp(argv[i], "-pedantic")) ||
-	         (!strcmp(argv[i], "--pedantic"))) {
-	    options |= XML_PARSE_PEDANTIC;
-            options &= ~XML_PARSE_NOWARNING;
-        }
-#ifdef LIBXML_DEBUG_ENABLED
-	else if ((!strcmp(argv[i], "-debugent")) ||
-		 (!strcmp(argv[i], "--debugent"))) {
-	    debugent++;
-	}
-#endif
-#ifdef LIBXML_C14N_ENABLED
-	else if ((!strcmp(argv[i], "-c14n")) ||
-		 (!strcmp(argv[i], "--c14n"))) {
-	    canonical++;
-	    options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
-	}
-	else if ((!strcmp(argv[i], "-c14n11")) ||
-		 (!strcmp(argv[i], "--c14n11"))) {
-	    canonical_11++;
-	    options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
-	}
-	else if ((!strcmp(argv[i], "-exc-c14n")) ||
-		 (!strcmp(argv[i], "--exc-c14n"))) {
-	    exc_canonical++;
-	    options |= XML_PARSE_NOENT | XML_PARSE_DTDATTR | XML_PARSE_DTDLOAD;
-	}
-#endif
 #ifdef LIBXML_CATALOG_ENABLED
-	else if ((!strcmp(argv[i], "-catalogs")) ||
-		 (!strcmp(argv[i], "--catalogs"))) {
-	    catalogs++;
-	} else if ((!strcmp(argv[i], "-nocatalogs")) ||
-		 (!strcmp(argv[i], "--nocatalogs"))) {
-	    nocatalogs++;
-	}
-#endif
-	else if ((!strcmp(argv[i], "-noblanks")) ||
-	         (!strcmp(argv[i], "--noblanks"))) {
-            options |= XML_PARSE_NOBLANKS;
-        }
-	else if ((!strcmp(argv[i], "-maxmem")) ||
-	         (!strcmp(argv[i], "--maxmem"))) {
-	     i++;
-        }
-#ifdef LIBXML_OUTPUT_ENABLED
-	else if ((!strcmp(argv[i], "-o")) ||
-	         (!strcmp(argv[i], "-output")) ||
-	         (!strcmp(argv[i], "--output"))) {
-	    i++;
-	    output = argv[i];
-	}
-	else if ((!strcmp(argv[i], "-format")) ||
-	         (!strcmp(argv[i], "--format"))) {
-	    format = 1;
-            options |= XML_PARSE_NOBLANKS;
-	}
-	else if ((!strcmp(argv[i], "-encode")) ||
-	         (!strcmp(argv[i], "--encode"))) {
-	    i++;
-	    encoding = argv[i];
-	    /*
-	     * OK it's for testing purposes
-	     */
-	    xmlAddEncodingAlias("UTF-8", "DVEnc");
-        }
-	else if ((!strcmp(argv[i], "-pretty")) ||
-	         (!strcmp(argv[i], "--pretty"))) {
-	    i++;
-            if (argv[i] != NULL)
-	        format = atoi(argv[i]);
-	}
-#ifdef LIBXML_ZLIB_ENABLED
-	else if ((!strcmp(argv[i], "-compress")) ||
-	         (!strcmp(argv[i], "--compress"))) {
-	    compress++;
-        }
-#endif
-#endif /* LIBXML_OUTPUT_ENABLED */
-#ifdef LIBXML_READER_ENABLED
-	else if ((!strcmp(argv[i], "-stream")) ||
-	         (!strcmp(argv[i], "--stream"))) {
-	     stream++;
-	}
-	else if ((!strcmp(argv[i], "-walker")) ||
-	         (!strcmp(argv[i], "--walker"))) {
-	     walker++;
-             noout++;
-        }
-#ifdef LIBXML_PATTERN_ENABLED
-        else if ((!strcmp(argv[i], "-pattern")) ||
-                   (!strcmp(argv[i], "--pattern"))) {
-	    i++;
-	    pattern = argv[i];
-	}
-#endif
-#endif /* LIBXML_READER_ENABLED */
-#ifdef LIBXML_SAX1_ENABLED
-	else if ((!strcmp(argv[i], "-sax1")) ||
-	         (!strcmp(argv[i], "--sax1"))) {
-	    options |= XML_PARSE_SAX1;
-	}
-#endif /* LIBXML_SAX1_ENABLED */
-	else if ((!strcmp(argv[i], "-sax")) ||
-	         (!strcmp(argv[i], "--sax"))) {
-	    sax++;
-        }
-#ifdef LIBXML_SCHEMAS_ENABLED
-	else if ((!strcmp(argv[i], "-relaxng")) ||
-	         (!strcmp(argv[i], "--relaxng"))) {
-	    i++;
-	    relaxng = argv[i];
-	    options |= XML_PARSE_NOENT;
-	} else if ((!strcmp(argv[i], "-schema")) ||
-	         (!strcmp(argv[i], "--schema"))) {
-	    i++;
-	    schema = argv[i];
-	    options |= XML_PARSE_NOENT;
-        }
-#endif
-#ifdef LIBXML_SCHEMATRON_ENABLED
-	else if ((!strcmp(argv[i], "-schematron")) ||
-	         (!strcmp(argv[i], "--schematron"))) {
-	    i++;
-	    schematron = argv[i];
-	    options |= XML_PARSE_NOENT;
-        }
-#endif
-        else if ((!strcmp(argv[i], "-nonet")) ||
-                   (!strcmp(argv[i], "--nonet"))) {
-	    options |= XML_PARSE_NONET;
-        } else if ((!strcmp(argv[i], "-nocompact")) ||
-                   (!strcmp(argv[i], "--nocompact"))) {
-	    options &= ~XML_PARSE_COMPACT;
-	} else if ((!strcmp(argv[i], "-load-trace")) ||
-	           (!strcmp(argv[i], "--load-trace"))) {
-	    load_trace++;
-        } else if ((!strcmp(argv[i], "-path")) ||
-                   (!strcmp(argv[i], "--path"))) {
-	    i++;
-	    parsePath(BAD_CAST argv[i]);
-        }
-#ifdef LIBXML_XPATH_ENABLED
-        else if ((!strcmp(argv[i], "-xpath")) ||
-                   (!strcmp(argv[i], "--xpath"))) {
-	    i++;
-	    noout++;
-	    xpathquery = argv[i];
-        }
-#endif
-	else if ((!strcmp(argv[i], "-oldxml10")) ||
-	           (!strcmp(argv[i], "--oldxml10"))) {
-	    options |= XML_PARSE_OLD10;
-	} else if ((!strcmp(argv[i], "-max-ampl")) ||
-	           (!strcmp(argv[i], "--max-ampl"))) {
-            i++;
-            if (i >= argc) {
-                fprintf(ERR_STREAM, "max-ampl: missing integer value\n");
-                return(XMLLINT_ERR_UNCLASS);
-            }
-            maxAmpl = parseInteger("max-ampl", argv[i], 1, UINT_MAX);
-	} else {
-	    fprintf(ERR_STREAM, "Unknown option %s\n", argv[i]);
-	    usage(ERR_STREAM, argv[0]);
-	    return(XMLLINT_ERR_UNCLASS);
-	}
-    }
-
-    if (shell)
-        repeat = 1;
-
-#ifdef LIBXML_CATALOG_ENABLED
-    if (nocatalogs == 0) {
-	if (catalogs) {
+    if (lint->nocatalogs == 0) {
+	if (lint->catalogs) {
 	    const char *catal;
 
 	    catal = getenv("SGML_CATALOG_FILES");
@@ -3299,123 +3287,133 @@
     }
 #endif
 
-    if ((htmlout) && (!nowrap)) {
-	fprintf(ERR_STREAM,
-         "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
-	fprintf(ERR_STREAM,
-		"\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
-	fprintf(ERR_STREAM,
-	 "<html><head><title>%s output</title></head>\n",
-		argv[0]);
-	fprintf(ERR_STREAM,
-	 "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
-		argv[0]);
+    if (lint->htmlout) {
+        lint->htmlBuf = xmlMalloc(HTML_BUF_SIZE);
+        if (lint->htmlBuf == NULL) {
+            lint->progresult = XMLLINT_ERR_MEM;
+            goto error;
+        }
+
+        if (!lint->nowrap) {
+            fprintf(ERR_STREAM,
+             "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"\n");
+            fprintf(ERR_STREAM,
+                    "\t\"http://www.w3.org/TR/REC-html40/loose.dtd\">\n");
+            fprintf(ERR_STREAM,
+             "<html><head><title>%s output</title></head>\n",
+                    argv[0]);
+            fprintf(ERR_STREAM,
+             "<body bgcolor=\"#ffffff\"><h1 align=\"center\">%s output</h1>\n",
+                    argv[0]);
+        }
     }
 
 #ifdef LIBXML_SCHEMATRON_ENABLED
-    if ((schematron != NULL) && (sax == 0)
+    if ((lint->schematron != NULL) && (lint->sax == 0)
 #ifdef LIBXML_READER_ENABLED
-        && (stream == 0)
+        && (lint->stream == 0)
 #endif /* LIBXML_READER_ENABLED */
 	) {
 	xmlSchematronParserCtxtPtr ctxt;
 
         /* forces loading the DTDs */
-	options |= XML_PARSE_DTDLOAD;
-	if (timing) {
-	    startTimer();
+	lint->options |= XML_PARSE_DTDLOAD;
+	if (lint->timing) {
+	    startTimer(lint);
 	}
-	ctxt = xmlSchematronNewParserCtxt(schematron);
+	ctxt = xmlSchematronNewParserCtxt(lint->schematron);
         if (ctxt == NULL) {
-            progresult = XMLLINT_ERR_MEM;
+            lint->progresult = XMLLINT_ERR_MEM;
             goto error;
         }
-	wxschematron = xmlSchematronParse(ctxt);
-	if (wxschematron == NULL) {
-	    fprintf(ERR_STREAM,
-		    "Schematron schema %s failed to compile\n", schematron);
-            progresult = XMLLINT_ERR_SCHEMACOMP;
-	    schematron = NULL;
+	lint->wxschematron = xmlSchematronParse(ctxt);
+	if (lint->wxschematron == NULL) {
+	    fprintf(ERR_STREAM, "Schematron schema %s failed to compile\n",
+                    lint->schematron);
+            lint->progresult = XMLLINT_ERR_SCHEMACOMP;
+            goto error;
 	}
 	xmlSchematronFreeParserCtxt(ctxt);
-	if (timing) {
-	    endTimer("Compiling the schemas");
+	if (lint->timing) {
+	    endTimer(lint, "Compiling the schemas");
 	}
     }
 #endif
+
 #ifdef LIBXML_SCHEMAS_ENABLED
-    if ((relaxng != NULL) && (sax == 0)
+    if ((lint->relaxng != NULL) && (lint->sax == 0)
 #ifdef LIBXML_READER_ENABLED
-        && (stream == 0)
+        && (lint->stream == 0)
 #endif /* LIBXML_READER_ENABLED */
 	) {
 	xmlRelaxNGParserCtxtPtr ctxt;
 
         /* forces loading the DTDs */
-	options |= XML_PARSE_DTDLOAD;
-	if (timing) {
-	    startTimer();
+	lint->options |= XML_PARSE_DTDLOAD;
+	if (lint->timing) {
+	    startTimer(lint);
 	}
-	ctxt = xmlRelaxNGNewParserCtxt(relaxng);
+	ctxt = xmlRelaxNGNewParserCtxt(lint->relaxng);
         if (ctxt == NULL) {
-            progresult = XMLLINT_ERR_MEM;
+            lint->progresult = XMLLINT_ERR_MEM;
             goto error;
         }
-        xmlRelaxNGSetResourceLoader(ctxt, xmllintResourceLoader, NULL);
-	relaxngschemas = xmlRelaxNGParse(ctxt);
-	if (relaxngschemas == NULL) {
-	    fprintf(ERR_STREAM,
-		    "Relax-NG schema %s failed to compile\n", relaxng);
-            progresult = XMLLINT_ERR_SCHEMACOMP;
-	    relaxng = NULL;
+        xmlRelaxNGSetResourceLoader(ctxt, xmllintResourceLoader, lint);
+	lint->relaxngschemas = xmlRelaxNGParse(ctxt);
+	if (lint->relaxngschemas == NULL) {
+	    fprintf(ERR_STREAM, "Relax-NG schema %s failed to compile\n",
+                    lint->relaxng);
+            lint->progresult = XMLLINT_ERR_SCHEMACOMP;
+            goto error;
 	}
 	xmlRelaxNGFreeParserCtxt(ctxt);
-	if (timing) {
-	    endTimer("Compiling the schemas");
+	if (lint->timing) {
+	    endTimer(lint, "Compiling the schemas");
 	}
-    } else if ((schema != NULL)
+    } else if ((lint->schema != NULL)
 #ifdef LIBXML_READER_ENABLED
-		&& (stream == 0)
+		&& (lint->stream == 0)
 #endif
 	) {
 	xmlSchemaParserCtxtPtr ctxt;
 
-	if (timing) {
-	    startTimer();
+	if (lint->timing) {
+	    startTimer(lint);
 	}
-	ctxt = xmlSchemaNewParserCtxt(schema);
+	ctxt = xmlSchemaNewParserCtxt(lint->schema);
         if (ctxt == NULL) {
-            progresult = XMLLINT_ERR_MEM;
+            lint->progresult = XMLLINT_ERR_MEM;
             goto error;
         }
-        xmlSchemaSetResourceLoader(ctxt, xmllintResourceLoader, NULL);
-	wxschemas = xmlSchemaParse(ctxt);
-	if (wxschemas == NULL) {
-	    fprintf(ERR_STREAM,
-		    "WXS schema %s failed to compile\n", schema);
-            progresult = XMLLINT_ERR_SCHEMACOMP;
-	    schema = NULL;
+        xmlSchemaSetResourceLoader(ctxt, xmllintResourceLoader, lint);
+	lint->wxschemas = xmlSchemaParse(ctxt);
+	if (lint->wxschemas == NULL) {
+	    fprintf(ERR_STREAM, "WXS schema %s failed to compile\n",
+                    lint->schema);
+            lint->progresult = XMLLINT_ERR_SCHEMACOMP;
+            goto error;
 	}
 	xmlSchemaFreeParserCtxt(ctxt);
-	if (timing) {
-	    endTimer("Compiling the schemas");
+	if (lint->timing) {
+	    endTimer(lint, "Compiling the schemas");
 	}
     }
 #endif /* LIBXML_SCHEMAS_ENABLED */
+
 #if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
-    if ((pattern != NULL) && (walker == 0)) {
-        patternc = xmlPatterncompile((const xmlChar *) pattern, NULL, 0, NULL);
-	if (patternc == NULL) {
-	    fprintf(ERR_STREAM,
-		    "Pattern %s failed to compile\n", pattern);
-            progresult = XMLLINT_ERR_SCHEMAPAT;
-	    pattern = NULL;
+    if ((lint->pattern != NULL) && (lint->walker == 0)) {
+        lint->patternc = xmlPatterncompile(BAD_CAST lint->pattern, NULL, 0,
+                                           NULL);
+	if (lint->patternc == NULL) {
+	    fprintf(ERR_STREAM, "Pattern %s failed to compile\n",
+                    lint->pattern);
+            lint->progresult = XMLLINT_ERR_SCHEMAPAT;
+            goto error;
 	}
     }
 #endif /* LIBXML_READER_ENABLED && LIBXML_PATTERN_ENABLED */
 
     for (i = 1; i < argc ; i++) {
-        xmlParserCtxtPtr ctxt;
         const char *filename = argv[i];
 #if HAVE_DECL_MMAP
         int memoryFd = -1;
@@ -3427,106 +3425,112 @@
         }
 
 #if HAVE_DECL_MMAP
-        if (memory) {
+        if (lint->memory) {
             struct stat info;
             if (stat(filename, &info) < 0) {
-                progresult = XMLLINT_ERR_RDFILE;
+                lint->progresult = XMLLINT_ERR_RDFILE;
                 break;
             }
             memoryFd = open(filename, O_RDONLY);
             if (memoryFd < 0) {
-                progresult = XMLLINT_ERR_RDFILE;
+                lint->progresult = XMLLINT_ERR_RDFILE;
                 break;
             }
-            memoryData = mmap(NULL, info.st_size + 1, PROT_READ, MAP_SHARED,
-                              memoryFd, 0);
-            if (memoryData == (void *) MAP_FAILED) {
+            lint->memoryData = mmap(NULL, info.st_size + 1, PROT_READ,
+                                    MAP_SHARED, memoryFd, 0);
+            if (lint->memoryData == (void *) MAP_FAILED) {
                 close(memoryFd);
                 fprintf(ERR_STREAM, "mmap failure for file %s\n", filename);
-                progresult = XMLLINT_ERR_RDFILE;
+                lint->progresult = XMLLINT_ERR_RDFILE;
                 break;
             }
-            memorySize = info.st_size;
+            lint->memorySize = info.st_size;
         }
 #endif /* HAVE_DECL_MMAP */
 
-	if ((timing) && (repeat > 1))
-	    startTimer();
+	if ((lint->timing) && (lint->repeat > 1))
+	    startTimer(lint);
 
 #ifdef LIBXML_HTML_ENABLED
-        if (html) {
-            ctxt = htmlNewParserCtxt();
+        if (lint->html) {
+            lint->ctxt = htmlNewParserCtxt();
         } else
 #endif
         {
-            ctxt = xmlNewParserCtxt();
+            lint->ctxt = xmlNewParserCtxt();
         }
-        if (ctxt == NULL) {
-            progresult = XMLLINT_ERR_MEM;
+        if (lint->ctxt == NULL) {
+            lint->progresult = XMLLINT_ERR_MEM;
             goto error;
         }
 
-        for (j = 0; j < repeat; j++) {
+        for (j = 0; j < lint->repeat; j++) {
 #ifdef LIBXML_READER_ENABLED
-            if (stream != 0) {
-                streamFile(filename);
+            if (lint->stream != 0) {
+                streamFile(lint, filename);
             } else {
 #endif /* LIBXML_READER_ENABLED */
-                if (sax) {
-                    testSAX(filename);
+                if (lint->sax) {
+                    testSAX(lint, filename);
                 } else {
-                    parseAndPrintFile(filename, ctxt);
+                    parseAndPrintFile(lint, filename);
                 }
 #ifdef LIBXML_READER_ENABLED
             }
 #endif /* LIBXML_READER_ENABLED */
         }
 
-        xmlFreeParserCtxt(ctxt);
+        xmlFreeParserCtxt(lint->ctxt);
 
-        if ((timing) && (repeat > 1)) {
-            endTimer("%d iterations", repeat);
+        if ((lint->timing) && (lint->repeat > 1)) {
+            endTimer(lint, "%d iterations", lint->repeat);
         }
 
         files += 1;
 
 #if HAVE_DECL_MMAP
-        if (memory) {
-            munmap(memoryData, memorySize);
+        if (lint->memory) {
+            munmap(lint->memoryData, lint->memorySize);
             close(memoryFd);
         }
 #endif
     }
-    if (generate)
-	parseAndPrintFile(NULL, NULL);
-    if ((htmlout) && (!nowrap)) {
+
+    if (lint->generate)
+	parseAndPrintFile(lint, NULL);
+
+    if ((lint->htmlout) && (!lint->nowrap)) {
 	fprintf(ERR_STREAM, "</body></html>\n");
     }
-    if ((files == 0) && (!generate) && (version == 0)) {
+
+    if ((files == 0) && (!lint->generate) && (lint->version == 0)) {
 	usage(ERR_STREAM, argv[0]);
-        progresult = XMLLINT_ERR_UNCLASS;
+        lint->progresult = XMLLINT_ERR_UNCLASS;
     }
 
 error:
 
+    if (lint->htmlout)
+        xmlFree(lint->htmlBuf);
+
 #ifdef LIBXML_SCHEMATRON_ENABLED
-    if (wxschematron != NULL)
-	xmlSchematronFree(wxschematron);
+    if (lint->wxschematron != NULL)
+	xmlSchematronFree(lint->wxschematron);
 #endif
 #ifdef LIBXML_SCHEMAS_ENABLED
-    if (relaxngschemas != NULL)
-	xmlRelaxNGFree(relaxngschemas);
-    if (wxschemas != NULL)
-	xmlSchemaFree(wxschemas);
+    if (lint->relaxngschemas != NULL)
+	xmlRelaxNGFree(lint->relaxngschemas);
+    if (lint->wxschemas != NULL)
+	xmlSchemaFree(lint->wxschemas);
 #endif
 #if defined(LIBXML_READER_ENABLED) && defined(LIBXML_PATTERN_ENABLED)
-    if (patternc != NULL)
-        xmlFreePattern(patternc);
+    if (lint->patternc != NULL)
+        xmlFreePattern(lint->patternc);
 #endif
 
     xmlCleanupParser();
 
-    return(progresult);
+    return(lint->progresult);
 }
 
 #ifndef XMLLINT_FUZZ