messing around with support for Windows path, cleanups, trying to identify

* include/libxml/xmlIO.h xmlIO.c parser.c HTMLparser.c DOCBparser.c:
  messing around with support for Windows path, cleanups,
  trying to identify and fix the various code path to the
  filename access. Added xmlNormalizeWindowsPath()
Daniel
diff --git a/DOCBparser.c b/DOCBparser.c
index e1d20c5..ddb08a2 100644
--- a/DOCBparser.c
+++ b/DOCBparser.c
@@ -6025,7 +6025,7 @@
     }
     memset(inputStream, 0, sizeof(docbParserInput));
 
-    inputStream->filename = xmlMemStrdup(filename);
+    inputStream->filename = xmlNormalizeWindowsPath(filename);
     inputStream->line = 1;
     inputStream->col = 1;
     inputStream->buf = buf;
diff --git a/HTMLparser.c b/HTMLparser.c
index 927cf2c..5f078d6 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -4881,7 +4881,7 @@
     }
     memset(inputStream, 0, sizeof(htmlParserInput));
 
-    inputStream->filename = xmlMemStrdup(filename);
+    inputStream->filename = xmlNormalizeWindowsPath(filename);
     inputStream->line = 1;
     inputStream->col = 1;
     inputStream->buf = buf;
diff --git a/include/libxml/xmlIO.h b/include/libxml/xmlIO.h
index 92aa179..7daa717 100644
--- a/include/libxml/xmlIO.h
+++ b/include/libxml/xmlIO.h
@@ -252,6 +252,7 @@
 					 const char *ID,
 					 xmlParserCtxtPtr ctxt);
 
+xmlChar *xmlNormalizeWindowsPath	(const xmlChar *path);
 
 /**
  * Default 'file://' protocol callbacks 
diff --git a/parser.c b/parser.c
index 0374f68..7311c9e 100644
--- a/parser.c
+++ b/parser.c
@@ -666,7 +666,7 @@
  
 static void deallocblankswrapper (xmlChar *str) {xmlFree(str);}
  
-xmlParserInputPtr
+static xmlParserInputPtr
 xmlNewBlanksWrapperInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
     xmlParserInputPtr input;
     xmlChar *buffer;
@@ -1808,12 +1808,11 @@
  * and the name for mismatch
  */
 
-xmlChar *
+static xmlChar *
 xmlParseNameAndCompare(xmlParserCtxtPtr ctxt, xmlChar const *other) {
     const xmlChar *cmp = other;
     const xmlChar *in;
     xmlChar *ret;
-    int count = 0;
 
     GROW;
     
@@ -2275,8 +2274,7 @@
 xmlChar *
 xmlParseAttValue(xmlParserCtxtPtr ctxt) {
     xmlChar limit = 0;
-    xmlChar *buf = NULL;
-    xmlChar *in = NULL;
+    const xmlChar *in = NULL;
     xmlChar *ret = NULL;
     SHRINK;
     GROW;
@@ -9002,7 +9000,8 @@
     if (filename == NULL)
 	inputStream->filename = NULL;
     else
-	inputStream->filename = xmlMemStrdup(filename);
+	inputStream->filename = (char *)
+	    xmlNormalizeWindowsPath((const xmlChar *) filename);
     inputStream->buf = buf;
     inputStream->base = inputStream->buf->buffer->content;
     inputStream->cur = inputStream->buf->buffer->content;
@@ -10021,6 +10020,7 @@
     xmlParserCtxtPtr ctxt;
     xmlParserInputPtr inputStream;
     char *directory = NULL;
+    xmlChar *normalized;
 
     ctxt = xmlNewParserCtxt();
     if (ctxt == NULL) {
@@ -10030,18 +10030,26 @@
 	return(NULL);
     }
 
-    inputStream = xmlLoadExternalEntity(filename, NULL, ctxt);
+    normalized = xmlNormalizeWindowsPath((const xmlChar *) filename);
+    if (normalized == NULL) {
+	xmlFreeParserCtxt(ctxt);
+	return(NULL);
+    }
+    inputStream = xmlLoadExternalEntity((char *) normalized, NULL, ctxt);
     if (inputStream == NULL) {
 	xmlFreeParserCtxt(ctxt);
+	xmlFree(normalized);
 	return(NULL);
     }
 
     inputPush(ctxt, inputStream);
     if ((ctxt->directory == NULL) && (directory == NULL))
-        directory = xmlParserGetDirectory(filename);
+        directory = xmlParserGetDirectory((char *) normalized);
     if ((ctxt->directory == NULL) && (directory != NULL))
         ctxt->directory = directory;
 
+    xmlFree(normalized);
+
     return(ctxt);
 }
 
diff --git a/xmlIO.c b/xmlIO.c
index 3cd4c2a..137ea03 100644
--- a/xmlIO.c
+++ b/xmlIO.c
@@ -123,6 +123,64 @@
 static int xmlOutputCallbackNr = 0;
 static int xmlOutputCallbackInitialized = 0;
 
+/************************************************************************
+ *									*
+ *		Handling of Windows file paths				*
+ *									*
+ ************************************************************************/
+
+#define IS_WINDOWS_PATH(p) 					\
+	((p != NULL) &&						\
+	 (((p[0] >= 'a') && (p[0] <= 'z')) ||			\
+	  ((p[0] >= 'A') && (p[0] <= 'Z'))) &&			\
+	 (p[1] == ':') && ((p[2] == '/') || (p[2] == '\\')))
+
+
+/**
+ * xmlNormalizeWindowsPath
+ * @path:  a windows path like "C:/foo/bar"
+ *
+ * Normalize a Windows path to make an URL from it
+ *
+ * Returns a new URI which must be freed by the caller or NULL
+ *   in case of error
+ */
+xmlChar *
+xmlNormalizeWindowsPath(const xmlChar *path)
+{
+    int len, i, j;
+    xmlChar *ret;
+
+    if (path == NULL)
+	return(NULL);
+    if (!IS_WINDOWS_PATH(path))
+	return(xmlStrdup(path));
+
+    len = xmlStrlen(path);
+    len += 10;
+    ret = xmlMalloc(len);
+    if (ret == NULL)
+	return(NULL);
+
+    ret[0] = 'f';
+    ret[1] = 'i';
+    ret[2] = 'l';
+    ret[3] = 'e';
+    ret[4] = ':';
+    ret[5] = '/';
+    ret[6] = '/';
+    ret[7] = '/';
+    for (i = 0,j = 8;i < len;i++,j++) {
+	/* TODO: UTF8 conversion + URI escaping ??? */
+	if (path[i] == '\\')
+	    ret[j] = '/';
+	else
+	    ret[j] = path[i];
+    }
+    ret[j] = 0;
+    return(ret);
+}
+
 /**
  * xmlCleanupInputCallbacks:
  *
@@ -296,7 +354,7 @@
 	return((void *) fd);
     }
 
-    if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost", 16))
+    if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17))
 #if defined (_WIN32) && !defined(__CYGWIN__)
 	path = &filename[17];
 #else
@@ -343,8 +401,12 @@
 	return((void *) fd);
     }
 
-    if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost", 16))
+    if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17))
+#if defined (_WIN32) && !defined(__CYGWIN__)
+	path = &filename[17];
+#else
 	path = &filename[16];
+#endif
     else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:///", 8)) {
 #if defined (_WIN32) && !defined(__CYGWIN__)
 	path = &filename[8];
@@ -460,8 +522,12 @@
 	return((void *) fd);
     }
 
-    if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost", 16))
+    if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17))
+#if defined (_WIN32) && !defined(__CYGWIN__)
+	path = &filename[17];
+#else
 	path = &filename[16];
+#endif
     else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:///", 8)) {
 #if defined (_WIN32) && !defined(__CYGWIN__)
 	path = &filename[8];
@@ -502,8 +568,12 @@
 	return((void *) fd);
     }
 
-    if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost", 16))
+    if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file://localhost/", 17))
+#if defined (_WIN32) && !defined(__CYGWIN__)
+	path = &filename[17];
+#else
 	path = &filename[16];
+#endif
     else if (!xmlStrncasecmp(BAD_CAST filename, BAD_CAST "file:///", 8)) {
 #if defined (_WIN32) && !defined(__CYGWIN__)
 	path = &filename[8];
@@ -1656,11 +1726,14 @@
     int i = 0;
     void *context = NULL;
     char *unescaped;
+    char *normalized;
 
     if (xmlInputCallbackInitialized == 0)
 	xmlRegisterDefaultInputCallbacks();
 
     if (URI == NULL) return(NULL);
+    normalized = (char *) xmlNormalizeWindowsPath((const xmlChar *)URI);
+    if (normalized == NULL) return(NULL);
 
 #ifdef LIBXML_CATALOG_ENABLED
 #endif
@@ -1670,7 +1743,7 @@
      * Go in reverse to give precedence to user defined handlers.
      * try with an unescaped version of the URI
      */
-    unescaped = xmlURIUnescapeString(URI, 0, NULL);
+    unescaped = xmlURIUnescapeString((char *) normalized, 0, NULL);
     if (unescaped != NULL) {
 	for (i = xmlInputCallbackNr - 1;i >= 0;i--) {
 	    if ((xmlInputCallbackTable[i].matchcallback != NULL) &&
@@ -1691,12 +1764,13 @@
 	for (i = xmlInputCallbackNr - 1;i >= 0;i--) {
 	    if ((xmlInputCallbackTable[i].matchcallback != NULL) &&
 		(xmlInputCallbackTable[i].matchcallback(URI) != 0)) {
-		context = xmlInputCallbackTable[i].opencallback(URI);
+		context = xmlInputCallbackTable[i].opencallback(normalized);
 		if (context != NULL)
 		    break;
 	    }
 	}
     }
+    xmlFree(normalized);
     if (context == NULL) {
 	return(NULL);
     }
@@ -1736,6 +1810,7 @@
     int i = 0;
     void *context = NULL;
     char *unescaped;
+    char *normalized;
 
     int is_http_uri = 0;	/*   Can't change if HTTP disabled  */
 
@@ -1743,11 +1818,13 @@
 	xmlRegisterDefaultOutputCallbacks();
 
     if (URI == NULL) return(NULL);
+    normalized = (char *) xmlNormalizeWindowsPath((const xmlChar *)URI);
+    if (normalized == NULL) return(NULL);
 
 #ifdef LIBXML_HTTP_ENABLED
     /*  Need to prevent HTTP URI's from falling into zlib short circuit  */
 
-    is_http_uri = xmlIOHTTPMatch( URI );
+    is_http_uri = xmlIOHTTPMatch( normalized );
 #endif
 
 
@@ -1756,7 +1833,7 @@
      * Go in reverse to give precedence to user defined handlers.
      * try with an unescaped version of the URI
      */
-    unescaped = xmlURIUnescapeString(URI, 0, NULL);
+    unescaped = xmlURIUnescapeString(normalized, 0, NULL);
     if (unescaped != NULL) {
 #ifdef HAVE_ZLIB_H
 	if ((compression > 0) && (compression <= 9) && (is_http_uri == 0)) {
@@ -1769,6 +1846,7 @@
 		    ret->closecallback = xmlGzfileClose;
 		}
 		xmlFree(unescaped);
+		xmlFree(normalized);
 		return(ret);
 	    }
 	}
@@ -1797,7 +1875,7 @@
     if (context == NULL) {
 #ifdef HAVE_ZLIB_H
 	if ((compression > 0) && (compression <= 9) && (is_http_uri == 0)) {
-	    context = xmlGzfileOpenW(URI, compression);
+	    context = xmlGzfileOpenW(normalized, compression);
 	    if (context != NULL) {
 		ret = xmlAllocOutputBuffer(encoder);
 		if (ret != NULL) {
@@ -1805,13 +1883,14 @@
 		    ret->writecallback = xmlGzfileWrite;
 		    ret->closecallback = xmlGzfileClose;
 		}
+		xmlFree(normalized);
 		return(ret);
 	    }
 	}
 #endif
 	for (i = xmlOutputCallbackNr - 1;i >= 0;i--) {
 	    if ((xmlOutputCallbackTable[i].matchcallback != NULL) &&
-		(xmlOutputCallbackTable[i].matchcallback(URI) != 0)) {
+		(xmlOutputCallbackTable[i].matchcallback(normalized) != 0)) {
 #if defined(LIBXML_HTTP_ENABLED) && defined(HAVE_ZLIB_H)
 		/*  Need to pass compression parameter into HTTP open calls  */
 		if (xmlOutputCallbackTable[i].matchcallback == xmlIOHTTPMatch)
@@ -1824,6 +1903,7 @@
 	    }
 	}
     }
+    xmlFree(normalized);
 
     if (context == NULL) {
 	return(NULL);
@@ -2450,8 +2530,12 @@
     if (URL == NULL)
 	return(0);
 
-    if (!xmlStrncasecmp(BAD_CAST URL, BAD_CAST "file://localhost", 16))
+    if (!xmlStrncasecmp(BAD_CAST URL, BAD_CAST "file://localhost/", 17))
+#if defined (_WIN32) && !defined(__CYGWIN__)
+	path = &URL[17];
+#else
 	path = &URL[16];
+#endif
     else if (!xmlStrncasecmp(BAD_CAST URL, BAD_CAST "file:///", 8)) {
 #if defined (_WIN32) && !defined(__CYGWIN__)
 	path = &URL[8];
@@ -2639,8 +2723,12 @@
     if (URL == NULL)
         return (0);
 
-    if (!xmlStrncasecmp(BAD_CAST URL, BAD_CAST "file://localhost", 16))
-        path = &URL[16];
+    if (!xmlStrncasecmp(BAD_CAST URL, BAD_CAST "file://localhost/", 17))
+#if defined (_WIN32) && !defined(__CYGWIN__)
+	path = &URL[17];
+#else
+	path = &URL[16];
+#endif
     else if (!xmlStrncasecmp(BAD_CAST URL, BAD_CAST "file:///", 8)) {
 #if defined (_WIN32) && !defined(__CYGWIN__)
         path = &URL[8];