bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 2/3] canonicalize-lgpl: Add basic tests for Mingw and first usefu


From: Jan Nieuwenhuizen
Subject: [PATCH 2/3] canonicalize-lgpl: Add basic tests for Mingw and first useful implementation.
Date: Fri, 25 Feb 2011 14:26:49 +0100

From: Jan Nieuwenhuizen <address@hidden>

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

        * lib/canonicalize-lgpl.c (__realpath)[WINDOWS]: Add an
        implementation for Mingw to pass newly added tests.

        * tests/test-canonicalize-lgpl.c (main)[WINDOWS]: Add test cases
        for Mingw, checking basic sanity.
---
 ChangeLog                      |    8 +++
 lib/canonicalize-lgpl.c        |  104 ++++++++++++++++++++++++++++++++++++++-
 tests/test-canonicalize-lgpl.c |   45 +++++++++++++++++
 3 files changed, 154 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 059c538..beef29d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 2011-02-25  Jan Nieuwenhuizen  <address@hidden>
 
+       * lib/canonicalize-lgpl.c (__realpath)[WINDOWS]: Add an
+       implementation for Mingw to pass newly added tests.
+
+       * tests/test-canonicalize-lgpl.c (main)[WINDOWS]: Add test cases
+       for Mingw, checking basic sanity.
+
+2011-02-25  Jan Nieuwenhuizen  <address@hidden>
+
        * tests/macros.h (GL_RM_RF): New macro: fallback for `rm -rf'.
        * tests/test-*.c: Use it.
 
diff --git a/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c
index 9bfb44f..c523bbe 100644
--- a/lib/canonicalize-lgpl.c
+++ b/lib/canonicalize-lgpl.c
@@ -95,10 +95,56 @@
    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 *
+backslashify (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 +190,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 +330,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 +418,12 @@ __realpath (const char *name, char *resolved)
   if (extra_buf)
     freea (extra_buf);
 
-  return rpath;
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+#ifndef GL_PREFER_SLASH_INTERNALLY
+  fname = backslashify (fname)
+#endif /* !GL_PREFER_SLASH_INTERNALLY */
+#endif /* (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ */
+  return fname;
 
 error:
   {
@@ -338,6 +432,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;
diff --git a/tests/test-canonicalize-lgpl.c b/tests/test-canonicalize-lgpl.c
index f020393..0cadf6b 100644
--- a/tests/test-canonicalize-lgpl.c
+++ b/tests/test-canonicalize-lgpl.c
@@ -98,6 +98,51 @@ main (void)
     ASSERT (errno == ENOENT);
   }
 
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+  /* Check basic drive letter sanity.  */
+  {
+    char *cwd;
+    char *test;
+    char *result;
+
+    /* Check if BASE has a canonical name.  */
+    result = canonicalize_file_name (BASE);
+    ASSERT (result != NULL);
+
+    /* Check if BASE's canonical name uses only one flavour of
+       dirsep.  */
+    ASSERT ((strchr (result, '/') == NULL)
+           != (strchr (result, '\\') == NULL));
+    free (result);
+
+    /* Check if CWD has a canonical name.  */
+    cwd = getcwd (NULL, 0);
+    result = canonicalize_file_name (cwd);
+    ASSERT (result != NULL);
+    free (result);
+
+    /* Check basic drive letter sanity.  */
+#ifdef GL_PREFER_SLASH_INTERNALLY
+    test = "c:/";
+#else /* !GL_PREFER_SLASH_INTERNALLY */
+    test = "c:\\";
+#endif /* !GL_PREFER_SLASH_INTERNALLY */
+    result = canonicalize_file_name (test);
+    ASSERT (strcmp (result, test) == 0);
+    free (result);
+
+    result = canonicalize_file_name ("C:\\");
+    ASSERT (strcmp (result, test) == 0);
+    free (result);
+
+    result = canonicalize_file_name ("C:");
+    ASSERT (strcmp (result, test) == 0);
+    free (result);
+
+    free (cwd);
+  }
+#endif /* (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ */
+
   /* From here on out, tests involve symlinks.  */
   if (symlink (BASE "/ket", "ise") != 0)
     {
-- 
1.7.1

-- 
Jan Nieuwenhuizen <address@hidden> | GNU LilyPond http://lilypond.org
Freelance IT http://JoyofSource.com | Avatar®  http://AvatarAcademy.nl  



reply via email to

[Prev in Thread] Current Thread [Next in Thread]