Bruno Haible schreef op di 01-02-2011 om 10:46 [+0100]:

Hi Bruno,

> In which respect did you find it useless for mingw?

In that, when given an absolute file name, such as

   c:/program files/lilypond/usr/share/guile/2.0/ice-9/boot-9.scm

it returns NULL.  It also returns NULL when given the CWD or a
simple drive letter, such as C: or C:/.  When given a local file
name "baz", it returns something like

    C:\foo\bar/baz

which is certainly not canonical.  Don't you think this is
pretty useless?

> I occasionally run it on mingw, and I don't remember having seen a
> test failure.

One reason could be that there is no single sensible test for
mingw.  It's still strange because for me, test-canonicalize-lgpl.exe
currently aborts in three places.

Attached are patches to get it to run, a patch adding some sane
tests for Mingw (ie, using a file name that includes a drive
letter), and a simple, much less broken implementation that I use
for running guile 1.9.

> So, before changing the implementation, I'd like to
> know what went wrong, and have a patch extend the unit test at the
> same time as the implementation.

It's good to see how thorough you are, even though I still think
this is not much of a change as much as a first implementation.

See attached, greetings,
Jan

-- 
Jan Nieuwenhuizen <[email protected]> | GNU LilyPond http://lilypond.org
Freelance IT http://JoyofSource.com | AvatarĀ®  http://AvatarAcademy.nl  
>From 4501819440a02d85b789701d402068a29f8f7413 Mon Sep 17 00:00:00 2001
From: Jan Nieuwenhuizen <[email protected]>
Date: Tue, 1 Feb 2011 13:24:28 +0100
Subject: [PATCH 1/6] Enable cross building along with basic HACKING instructions.

2011-02-01  Jan Nieuwenhuizen  <[email protected]>

	* gnulib-tool: Enable cross building.
	* HACKING: New file, also documenting cross building.
---
 ChangeLog   |    5 +++++
 HACKING     |   20 ++++++++++++++++++++
 gnulib-tool |    2 +-
 3 files changed, 26 insertions(+), 1 deletions(-)
 create mode 100644 HACKING

diff --git a/ChangeLog b/ChangeLog
index b025454..e847952 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2011-02-01  Jan Nieuwenhuizen  <[email protected]>
+
+	* gnulib-tool: Enable cross building.
+	* HACKING: New file, also documenting cross building.
+
 2011-01-31  Eric Blake  <[email protected]>
 
 	dup2: work around Haiku bug
diff --git a/HACKING b/HACKING
new file mode 100644
index 0000000..ff6089b
--- /dev/null
+++ b/HACKING
@@ -0,0 +1,20 @@
+Gnulib Hacking Guide
+
+Before changing or adding any code, write a test that fails (see
+README).
+
+After adding a test to test/canonicalize-lgpl.c, use gnulib-tools
+to verify that it fails, do something like
+
+    ./gnulib-tools --dir=work --test canonicalize-lgpl --with-tests
+
+Testing mingw32
+
+    PATH=$HOME/vc/gub/target/mingw/root/usr/cross/bin:$PATH CFLAGS='-W -Wall' CONFIGURE_ARGS=--host=i686-mingw32 ./gnulib-tool --dir=mingw --test --with-tests canonicalize-lgpl
+
+    cd mingw/build
+
+    ...do some hacking...
+    
+    PATH=$HOME/vc/gub/target/mingw/root/usr/cross/bin:$PATH make
+    gltests/test-canonicalize-lgpl.exe
diff --git a/gnulib-tool b/gnulib-tool
index 9375f97..7457dde 100755
--- a/gnulib-tool
+++ b/gnulib-tool
@@ -5736,7 +5736,7 @@ s/\([.*$]\)/[\1]/g'
     cd "$destdir"
       mkdir build
       cd build
-        ../configure || func_exit 1
+        ../configure "$CONFIGURE_ARGS" || func_exit 1
         $MAKE || func_exit 1
         $MAKE check || func_exit 1
         $MAKE distclean || func_exit 1
-- 
1.7.1

>From cb67060d5bbcc168df25919dab31257fcaca6e44 Mon Sep 17 00:00:00 2001
From: Jan Nieuwenhuizen <[email protected]>
Date: Tue, 1 Feb 2011 13:28:30 +0100
Subject: [PATCH 2/6] canonicalize-lgpl: Use del instead of rm.  Fixes aborting on initial cleanup.

2011-02-01  Jan Nieuwenhuizen  <[email protected]>

	* tests/test-canonicalize-lgpl.c (main)[__MINGW32__]: Use del
	instead of rm.  Fixes aborting on initial cleanup.

Test output without this fix:

    13:00:24 janneke@vuurvlieg:~/vc/gnulib/mingw/build
    $ LANG= gltests/test-canonicalize-lgpl.exe
    wine: cannot find L"C:\\windows\\system32\\rm.exe"
    File not found

    test-canonicalize-lgpl.c:60: assertion failed
    [3]13:00:31 janneke@vuurvlieg:~/vc/gnulib/mingw/build
---
 ChangeLog                      |    5 +++++
 tests/test-canonicalize-lgpl.c |    5 +++++
 2 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index e847952..3d53946 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2011-02-01  Jan Nieuwenhuizen  <[email protected]>
 
+	* tests/test-canonicalize-lgpl.c (main)[__MINGW32__]: Use del
+	instead of rm.  Fixes aborting on initial cleanup.
+
+2011-02-01  Jan Nieuwenhuizen  <[email protected]>
+
 	* gnulib-tool: Enable cross building.
 	* HACKING: New file, also documenting cross building.
 
diff --git a/tests/test-canonicalize-lgpl.c b/tests/test-canonicalize-lgpl.c
index 17cdff0..02b3411 100644
--- a/tests/test-canonicalize-lgpl.c
+++ b/tests/test-canonicalize-lgpl.c
@@ -56,8 +56,13 @@ main (void)
      any leftovers from a previous partial run.  */
   {
     int fd;
+#ifndef __MINGW32__
     ignore_value (system ("rm -rf " BASE " ise"));
     ASSERT (mkdir (BASE, 0700) == 0);
+#else  /* __MINGW32__ */
+    ignore_value (system ("del /r /q " BASE " ise"));
+    fprintf (stderr, "mkdir:%d\n", mkdir (BASE, 0777)); // FIXME
+#endif /* __MINGW32__ */
     fd = creat (BASE "/tra", 0600);
     ASSERT (0 <= fd);
     ASSERT (close (fd) == 0);
-- 
1.7.1

>From 6ea87bfbd34db4aa1f26024dfeca1bdbdc394505 Mon Sep 17 00:00:00 2001
From: Jan Nieuwenhuizen <[email protected]>
Date: Tue, 1 Feb 2011 13:38:37 +0100
Subject: [PATCH 3/6] canonicalize-lgpl: Skip symlink tests. Fixes aborting on symlink tests.

2011-02-01  Jan Nieuwenhuizen  <[email protected]>

	* tests/test-canonicalize-lgpl.c (main)[__MINGW32__]: Skip symlink
	tests.  Fixes aborting on symlink tests.

Test output without this fix:

    13:17:39 janneke@vuurvlieg:~/vc/gnulib/mingw/build
    $ LANG= gltests/test-canonicalize-lgpl.exe
    ise : File Not Found
    mkdir:-1
    fixme:msvcrt:MSVCRT__sopen : pmode 0x60fd88 ignored
    skipping test: symlinks not supported on this file system
    [77]
---
 ChangeLog                      |    5 +++++
 tests/test-canonicalize-lgpl.c |    3 +++
 2 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 3d53946..2fe66c9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2011-02-01  Jan Nieuwenhuizen  <[email protected]>
 
+	* tests/test-canonicalize-lgpl.c (main)[__MINGW32__]: Skip symlink
+	tests.  Fixes aborting on symlink tests.
+
+2011-02-01  Jan Nieuwenhuizen  <[email protected]>
+
 	* tests/test-canonicalize-lgpl.c (main)[__MINGW32__]: Use del
 	instead of rm.  Fixes aborting on initial cleanup.
 
diff --git a/tests/test-canonicalize-lgpl.c b/tests/test-canonicalize-lgpl.c
index 02b3411..f80b55d 100644
--- a/tests/test-canonicalize-lgpl.c
+++ b/tests/test-canonicalize-lgpl.c
@@ -103,6 +103,8 @@ main (void)
     ASSERT (errno == ENOENT);
   }
 
+#ifndef __MINGW32__
+
   /* From here on out, tests involve symlinks.  */
   if (symlink (BASE "/ket", "ise") != 0)
     {
@@ -210,6 +212,7 @@ main (void)
     free (result2);
   }
 
+#endif /* !__MINGW32__ */
 
   /* Cleanup.  */
   ASSERT (remove (BASE "/droot") == 0);
-- 
1.7.1

>From dce78b34da0b5d1a765594d98d5776814098d7a2 Mon Sep 17 00:00:00 2001
From: Jan Nieuwenhuizen <[email protected]>
Date: Tue, 1 Feb 2011 13:43:12 +0100
Subject: [PATCH 4/6] canonicalize-lgpl: Skip cleanup using remove. Fixes aborting on cleanups.

2011-02-01  Jan Nieuwenhuizen  <[email protected]>

	* tests/test-canonicalize-lgpl.c (main)[__MINGW32__]: Skip cleanup using
	remove.  Fixes aborting on cleanups.  We do an initial cleanup anyway.
---
 ChangeLog                      |    5 +++++
 tests/test-canonicalize-lgpl.c |    6 +++---
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 2fe66c9..94a9a6a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2011-02-01  Jan Nieuwenhuizen  <[email protected]>
 
+	* tests/test-canonicalize-lgpl.c (main)[__MINGW32__]: Skip cleanup using
+	remove.  Fixes aborting on cleanups.  We do an initial cleanup anyway.
+
+2011-02-01  Jan Nieuwenhuizen  <[email protected]>
+
 	* tests/test-canonicalize-lgpl.c (main)[__MINGW32__]: Skip symlink
 	tests.  Fixes aborting on symlink tests.
 
diff --git a/tests/test-canonicalize-lgpl.c b/tests/test-canonicalize-lgpl.c
index f80b55d..49f8643 100644
--- a/tests/test-canonicalize-lgpl.c
+++ b/tests/test-canonicalize-lgpl.c
@@ -103,7 +103,9 @@ main (void)
     ASSERT (errno == ENOENT);
   }
 
-#ifndef __MINGW32__
+#ifdef __MINGW32__
+  return 0;
+#endif /* __MINGW32__ */
 
   /* From here on out, tests involve symlinks.  */
   if (symlink (BASE "/ket", "ise") != 0)
@@ -212,8 +214,6 @@ main (void)
     free (result2);
   }
 
-#endif /* !__MINGW32__ */
-
   /* Cleanup.  */
   ASSERT (remove (BASE "/droot") == 0);
   ASSERT (remove (BASE "/plo") == 0);
-- 
1.7.1

>From 0a9d1313a7e47c96a47e770edac1d1435bb4c1d9 Mon Sep 17 00:00:00 2001
From: Jan Nieuwenhuizen <[email protected]>
Date: Tue, 1 Feb 2011 14:26:19 +0100
Subject: [PATCH 5/6] canonicalize-lgpl: Add basic sanity checks for mingw.

2011-02-01  Jan Nieuwenhuizen  <[email protected]>

	* tests/test-canonicalize-lgpl.c (main)[__MINGW32__]: Add basic sanity
	checks for mingw along with debug printing to demonstrate brokenness.
---
 ChangeLog                      |    5 +++++
 tests/test-canonicalize-lgpl.c |   34 ++++++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 94a9a6a..86217e6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2011-02-01  Jan Nieuwenhuizen  <[email protected]>
 
+	* tests/test-canonicalize-lgpl.c (main)[__MINGW32__]: Add basic sanity
+	checks for mingw along with debug printing to demonstrate brokenness.
+
+2011-02-01  Jan Nieuwenhuizen  <[email protected]>
+
 	* tests/test-canonicalize-lgpl.c (main)[__MINGW32__]: Skip cleanup using
 	remove.  Fixes aborting on cleanups.  We do an initial cleanup anyway.
 
diff --git a/tests/test-canonicalize-lgpl.c b/tests/test-canonicalize-lgpl.c
index 49f8643..18f0005 100644
--- a/tests/test-canonicalize-lgpl.c
+++ b/tests/test-canonicalize-lgpl.c
@@ -104,7 +104,41 @@ main (void)
   }
 
 #ifdef __MINGW32__
+
+  /* Check basic drive letter sanity.  */
+  {
+    char cwd[PATH_MAX];
+    char *test;
+    char *result;
+
+    /* Check if BASE has a canonical name.  */
+    result = canonicalize_file_name (BASE);
+    fprintf (stderr, "BASE-canon: %s\n", result);
+    ASSERT (result != NULL);
+
+    /* Check if BASE's canonical name is somewhat canonical.  */
+    ASSERT ((strchr (result, '/') == NULL)
+	    != (strchr (result, '\\') == NULL));
+
+    /* Check if CWD has a canonical name.  */
+    getcwd (cwd, PATH_MAX);
+    fprintf (stderr, "CWD: %s\n", cwd);
+    result = canonicalize_file_name (cwd);
+    fprintf (stderr, "CWD-canon: %s\n", result);
+    ASSERT (result != NULL);
+
+    /* Check basic drive letter sanity.  */
+    test = "c:/";
+    result = canonicalize_file_name (test);
+    ASSERT (strcmp (result, test) == 0);
+    fprintf (stderr, "C:/-canon: %s\n", result);
+    result = canonicalize_file_name ("C:\\");
+    ASSERT (strcmp (result, test) == 0);
+    fprintf (stderr, "C:\\-canon: %s\n", result);
+  }
+
   return 0;
+
 #endif /* __MINGW32__ */
 
   /* From here on out, tests involve symlinks.  */
-- 
1.7.1

>From e8f8f8dc840bfd2c960f86a5e6799420ec755e8c Mon Sep 17 00:00:00 2001
From: Jan Nieuwenhuizen <[email protected]>
Date: Tue, 1 Feb 2011 14:47:50 +0100
Subject: [PATCH 6/6] canonicalize-lgpl: Add an implementation for canonicalize_file_name.

2011-02-01  Jan Nieuwenhuizen  <[email protected]>

	* lib/canonicalize-lgpl.c (__realpath)[__MINGW32__]: Add an
	implementation for canonicalize_file_name.  This marked the first
	running of guile.exe (1.9) in wine.

	* tests/test-canonicalize-lgpl.c (main)[__MINGW32__]: Do not abort
	on `nonexistent/..'; in Windows that works fine.
---
 ChangeLog                      |    9 ++++
 lib/canonicalize-lgpl.c        |   87 ++++++++++++++++++++++++++++++++++++++++
 tests/test-canonicalize-lgpl.c |    8 ++++
 3 files changed, 104 insertions(+), 0 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 86217e6..112f02e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2011-02-01  Jan Nieuwenhuizen  <[email protected]>
 
+	* lib/canonicalize-lgpl.c (__realpath)[__MINGW32__]: Add an
+	implementation for canonicalize_file_name.  This marked the first
+	running of guile.exe (1.9) in wine.
+
+	* tests/test-canonicalize-lgpl.c (main)[__MINGW32__]: Do not abort
+	on `nonexistent/..'; in Windows that works fine.
+
+2011-02-01  Jan Nieuwenhuizen  <[email protected]>
+
 	* tests/test-canonicalize-lgpl.c (main)[__MINGW32__]: Add basic sanity
 	checks for mingw along with debug printing to demonstrate brokenness.
 
diff --git a/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c
index 9bfb44f..3c22195 100644
--- a/lib/canonicalize-lgpl.c
+++ b/lib/canonicalize-lgpl.c
@@ -84,6 +84,9 @@
 #endif
 
 #if !FUNC_REALPATH_WORKS || defined _LIBC
+
+#ifndef __MINGW32__
+
 /* Return the canonical absolute name of file NAME.  A canonical name
    does not contain any `.', `..' components nor any repeated path
    separators ('/') or symlinks.  All path components must exist.  If
@@ -342,6 +345,90 @@ error:
   }
   return NULL;
 }
+
+#else /* __MINGW32__ */
+#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 *
+strlower (char *str)
+{
+  char *p = str;
+  while (*p)
+    {
+      *p = (char)tolower (*p);
+      p++;
+    }
+  return str;
+}
+
+char *
+__realpath (const char *name, char *resolved)
+{
+  char *rpath = NULL;
+
+  if (name == NULL)
+    {
+      /* As per Single Unix Specification V2 we must return an error if
+         either parameter is a null pointer.  We extend this to allow
+         the RESOLVED parameter to be NULL in case the we are expected to
+         allocate the room for the return value.  */
+      __set_errno (EINVAL);
+      return NULL;
+    }
+
+  if (name[0] == '\0')
+    {
+      /* As per Single Unix Specification V2 we must return an error if
+         the name argument points to an empty string.  */
+      __set_errno (ENOENT);
+      return NULL;
+    }
+
+  if (resolved == NULL)
+    {
+      rpath = malloc (PATH_MAX + 1);
+      if (rpath == NULL)
+        {
+          /* It's easier to set errno to ENOMEM than to rely on the
+             'malloc-posix' gnulib module.  */
+          errno = ENOMEM;
+          return NULL;
+        }
+    }
+  else
+    rpath = resolved;
+
+  GetFullPathName (name, PATH_MAX, rpath, NULL);
+  slashify (rpath);
+  strlower (rpath);
+  struct stat st;
+  if (lstat (rpath, &st) < 0)
+    {
+      if (resolved == NULL)
+	free (rpath);
+      return NULL;
+    }
+  return rpath;
+}
+
+#endif /* __MINGW32__ */
+
 versioned_symbol (libc, __realpath, realpath, GLIBC_2_3);
 #endif /* !FUNC_REALPATH_WORKS || defined _LIBC */
 
diff --git a/tests/test-canonicalize-lgpl.c b/tests/test-canonicalize-lgpl.c
index 18f0005..ff7664d 100644
--- a/tests/test-canonicalize-lgpl.c
+++ b/tests/test-canonicalize-lgpl.c
@@ -98,9 +98,17 @@ main (void)
   {
     char *result;
     errno = 0;
+    result = canonicalize_file_name (BASE "/zzz");
+    ASSERT (result == NULL);
+    ASSERT (errno == ENOENT);
     result = canonicalize_file_name (BASE "/zzz/..");
+#ifndef __MINGW32__
     ASSERT (result == NULL);
     ASSERT (errno == ENOENT);
+#else /* __MINGW32__ */
+    /* Windows is OK with asking for: non-existent/.. */
+    ASSERT (result != NULL);
+#endif /* __MINGW32__ */
   }
 
 #ifdef __MINGW32__
-- 
1.7.1

Reply via email to