>From d5b578b84e638c1223de3b25f9614844206673c2 Mon Sep 17 00:00:00 2001
From: Jan Nieuwenhuizen <address@hidden>
Date: Fri, 4 Feb 2011 18:49:54 +0100
Subject: [PATCH 3/4] canonicalize-lgpl: Add an implementation for mingw to pass newly added tests.

2011-02-04  Jan Nieuwenhuizen  <address@hidden>

	* lib/canonicalize-lgpl.c (__realpath)[(_WIN32 || __WIN32__) && ! __CYGWIN__]:
	Add an implementation for mingw to pass newly added tests.
---
 ChangeLog               |    5 +++
 lib/canonicalize-lgpl.c |   85 +++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 87 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 24d1998..f984aa8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2011-02-04  Jan Nieuwenhuizen  <address@hidden>
 
+	* lib/canonicalize-lgpl.c (__realpath)[(_WIN32 || __WIN32__) && ! __CYGWIN__]:
+	Add an implementation for mingw to pass newly added tests.
+
+2011-02-04  Jan Nieuwenhuizen  <address@hidden>
+
 	* tests/test-canonicalize-lgpl.c (main)[(_WIN32 || __WIN32__) && ! __CYGWIN__]: 
 	Add basic sanity checks for mingw along with debug printing demonstrating
 	general breakage.
diff --git a/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c
index 9bfb44f..4a58aa8 100644
--- a/lib/canonicalize-lgpl.c
+++ b/lib/canonicalize-lgpl.c
@@ -95,10 +95,42 @@
    that cannot be resolved.  If the path can be resolved, RESOLVED
    holds the same value as the value returned.  */
 
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+#include <ctype.h>
+#include <direct.h>
+#include <windows.h>
+
+static char const *
+slashify (char const *str)
+{
+  char *p = (char*)str;
+  
+  while (*p)
+    {
+      if (*p == '\\')
+	*p = '/';
+      p++;
+    }
+  return str;
+}
+
+static char const *
+strlower (char const *str)
+{
+  char *p = (char*)str;
+  while (*p)
+    {
+      *p = (char)tolower (*p);
+      p++;
+    }
+  return str;
+}
+#endif /* (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ */
+
 char *
 __realpath (const char *name, char *resolved)
 {
-  char *rpath, *dest, *extra_buf = NULL;
+  char *fname, *rpath, *dest, *extra_buf = NULL, *sname = NULL;
   const char *start, *end, *rpath_limit;
   long int path_max;
   int num_links = 0;
@@ -144,6 +176,49 @@ __realpath (const char *name, char *resolved)
     rpath = resolved;
   rpath_limit = rpath + path_max;
 
+  fname = rpath;
+
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+  {
+    sname = malloc (PATH_MAX);
+    if (sname == NULL)
+      goto error;
+    strcpy (sname, name);
+    name = strlower (slashify (sname));
+  }
+  if (name[1] && (name[1] != ':' || name[2] != '/'))
+    {
+      DWORD cwd_len;
+      char root[3] = ".";
+
+      if (name[0] == '/')
+	{
+	  root[0] = *name++;
+	  root[1] = '\0';
+	}
+      else if (name[1] == ':')
+	{
+	  root[0] = *name++;
+	  root[1] = *name++;
+	  root[2] = '\0';
+	}
+
+      cwd_len = GetFullPathName (root, PATH_MAX, fname, NULL);
+      if (!cwd_len)
+	goto error;
+      strlower (slashify (fname));
+      rpath = fname + cwd_len - 1;
+    }
+    else
+      {
+	strncpy (fname, name, 3);
+	name += 2;
+	rpath = fname + 3;
+      }
+  if (1)
+    dest = rpath + 1;
+  else
+#endif /* (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ */
   if (name[0] != '/')
     {
       if (!__getcwd (rpath, path_max))
@@ -241,7 +316,7 @@ __realpath (const char *name, char *resolved)
 #ifdef _LIBC
           if (__lxstat64 (_STAT_VER, rpath, &st) < 0)
 #else
-          if (lstat (rpath, &st) < 0)
+          if (lstat (fname, &st) < 0)
 #endif
             goto error;
 
@@ -329,7 +404,7 @@ __realpath (const char *name, char *resolved)
   if (extra_buf)
     freea (extra_buf);
 
-  return rpath;
+  return fname;
 
 error:
   {
@@ -338,6 +413,10 @@ error:
       freea (extra_buf);
     if (resolved == NULL)
       free (rpath);
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+    if (sname != NULL)
+      free (sname);
+#endif /* (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ */
     errno = saved_errno;
   }
   return NULL;
-- 
1.7.1