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