> From: Andy Wingo <wi...@pobox.com>
> Cc: guile-devel@gnu.org
> Date: Sat, 16 Jul 2016 10:33:56 +0200
> 
> > Can these please be applied?
> 
> Sure let's work on it.  Would you mind submitting these again, making
> sure they apply cleanly to stable-2.0?

3 patches against the current stable-2.0 are attached.

>From 8a1e4631fc2dddf5ca63039b4a77ae0d33d3cb90 Mon Sep 17 00:00:00 2001
From: Eli Zaretskii <e...@gnu.org>
Date: Sat, 16 Jul 2016 14:17:25 +0300
Subject: [PATCH] Open temporary files in binary mode on MS-Windows

* libguile/filesys.c (scm_mkstemp) [__MINGW32__]: Make sure the
temporary file is open in binary mode.
---
 libguile/filesys.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/libguile/filesys.c b/libguile/filesys.c
index 48232e8..c47c2f4 100644
--- a/libguile/filesys.c
+++ b/libguile/filesys.c
@@ -1472,6 +1472,14 @@ SCM_DEFINE (scm_mkstemp, "mkstemp!", 1, 0, 0,
   SCM_SYSCALL (rv = mkstemp (c_tmpl));
   if (rv == -1)
     SCM_SYSERROR;
+#ifdef __MINGW32__
+  /* Files created by this function are used for *.go files, so make
+     sure they use binary I/O, or else the produced *.go files will be
+     corrupted by end-of-line conversion and ^Z "software EOF"
+     misfeature.  Gnulib's 'mkstemp' uses the default text mode to
+     open the file .  */
+  _setmode (rv, _O_BINARY);
+#endif
 
   scm_substring_move_x (scm_from_locale_string (c_tmpl),
 			SCM_INUM0, scm_string_length (tmpl),
-- 
2.9.0.windows.1

>From f598db99c0da4aefce0b393f52a4da8f0c4c055e Mon Sep 17 00:00:00 2001
From: Eli Zaretskii <e...@gnu.org>
Date: Sat, 16 Jul 2016 14:20:23 +0300
Subject: [PATCH] Fix 'dirname' and 'basename' on MS-Windows

* libguile/filesys.c (is_drive_letter): New helper function.
(scm_dirname, scm_basename): Use it.  Don't assume the leading
slash is always at the beginning of the file name.  Support UNC
file names on MS-Windows.
---
 libguile/filesys.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 76 insertions(+), 11 deletions(-)

diff --git a/libguile/filesys.c b/libguile/filesys.c
index c47c2f4..55df768 100644
--- a/libguile/filesys.c
+++ b/libguile/filesys.c
@@ -449,6 +449,18 @@ is_file_name_separator (SCM c)
   return 0;
 }
 
+static int
+is_drive_letter (SCM c)
+{
+#ifdef __MINGW32__
+  if (SCM_CHAR (c) >= 'a' && SCM_CHAR (c) <= 'z')
+    return 1;
+  else if (SCM_CHAR (c) >= 'A' && SCM_CHAR (c) <= 'Z')
+    return 1;
+#endif
+  return 0;
+}
+
 SCM_DEFINE (scm_stat, "stat", 1, 1, 0, 
             (SCM object, SCM exception_on_error),
 	    "Return an object containing various information about the file\n"
@@ -1522,24 +1534,60 @@ SCM_DEFINE (scm_dirname, "dirname", 1, 0, 0,
 {
   long int i;
   unsigned long int len;
+  /* Length of prefix before the top-level slash.  Always zero on
+     Posix hosts, but may be non-zero on Windows.  */
+  long prefix_len = 0;
+  int is_unc = 0;
+  unsigned long unc_end = 0;
 
   SCM_VALIDATE_STRING (1, filename);
 
   len = scm_i_string_length (filename);
+  if (len >= 2
+      && is_drive_letter (scm_c_string_ref (filename, 0))
+      && scm_is_eq (scm_c_string_ref (filename, 1), SCM_MAKE_CHAR (':')))
+    {
+      prefix_len = 1;
+      if (len > 2 && is_file_name_separator (scm_c_string_ref (filename, 2)))
+	prefix_len++;
+    }
+#ifdef __MINGW32__
+  if (len > 1
+      && is_file_name_separator (scm_c_string_ref (filename, 0))
+      && is_file_name_separator (scm_c_string_ref (filename, 1)))
+    {
+      is_unc = 1;
+      prefix_len = 1;
+    }
+#endif
 
   i = len - 1;
 
-  while (i >= 0 && is_file_name_separator (scm_c_string_ref (filename, i)))
+  while (i >= prefix_len
+	 && is_file_name_separator (scm_c_string_ref (filename, i)))
     --i;
-  while (i >= 0 && !is_file_name_separator (scm_c_string_ref (filename, i)))
+  if (is_unc)
+    unc_end = i + 1;
+  while (i >= prefix_len
+	 && !is_file_name_separator (scm_c_string_ref (filename, i)))
     --i;
-  while (i >= 0 && is_file_name_separator (scm_c_string_ref (filename, i)))
+  while (i >= prefix_len
+	 && is_file_name_separator (scm_c_string_ref (filename, i)))
     --i;
 
-  if (i < 0)
+  if (i < prefix_len)
     {
-      if (len > 0 && is_file_name_separator (scm_c_string_ref (filename, 0)))
-	return scm_c_substring (filename, 0, 1);
+      if (is_unc)
+	return scm_c_substring (filename, 0, unc_end);
+      else if (len > prefix_len
+	  && is_file_name_separator (scm_c_string_ref (filename, prefix_len)))
+	return scm_c_substring (filename, 0, prefix_len + 1);
+#ifdef __MINGW32__
+      else if (len > prefix_len
+	       && scm_is_eq (scm_c_string_ref (filename, 1),
+			     SCM_MAKE_CHAR (':')))
+	return scm_c_substring (filename, 0, prefix_len + 1);
+#endif
       else
 	return scm_dot_string;
     }
@@ -1557,6 +1605,9 @@ SCM_DEFINE (scm_basename, "basename", 1, 1, 0,
 #define FUNC_NAME s_scm_basename
 {
   int i, j, len, end;
+  /* Length of prefix before the top-level slash.  Always zero on
+     Posix hosts, but may be non-zero on Windows.  */
+  long prefix_len = 0;
 
   SCM_VALIDATE_STRING (1, filename);
   len = scm_i_string_length (filename);
@@ -1568,11 +1619,17 @@ SCM_DEFINE (scm_basename, "basename", 1, 1, 0,
       SCM_VALIDATE_STRING (2, suffix);
       j = scm_i_string_length (suffix) - 1;
     }
+  if (len >= 2
+      && is_drive_letter (scm_c_string_ref (filename, 0))
+      && scm_is_eq (scm_c_string_ref (filename, 1), SCM_MAKE_CHAR (':')))
+    prefix_len = 2;
+
   i = len - 1;
-  while (i >= 0 && is_file_name_separator (scm_c_string_ref (filename, i)))
+  while (i >= prefix_len
+	 && is_file_name_separator (scm_c_string_ref (filename, i)))
     --i;
   end = i;
-  while (i >= 0 && j >= 0 
+  while (i >= prefix_len && j >= 0
 	 && (scm_i_string_ref (filename, i)
 	     == scm_i_string_ref (suffix, j)))
     {
@@ -1581,12 +1638,20 @@ SCM_DEFINE (scm_basename, "basename", 1, 1, 0,
     }
   if (j == -1)
     end = i;
-  while (i >= 0 && !is_file_name_separator (scm_c_string_ref (filename, i)))
+  while (i >= prefix_len
+	 && !is_file_name_separator (scm_c_string_ref (filename, i)))
     --i;
   if (i == end)
     {
-      if (len > 0 && is_file_name_separator (scm_c_string_ref (filename, 0)))
-        return scm_c_substring (filename, 0, 1);
+      if (len > prefix_len
+	  && is_file_name_separator (scm_c_string_ref (filename, prefix_len)))
+        return scm_c_substring (filename, 0, prefix_len + 1);
+#ifdef __MINGW32__
+      else if (len > prefix_len
+	       && scm_is_eq (scm_c_string_ref (filename, 1),
+			     SCM_MAKE_CHAR (':')))
+	return scm_c_substring (filename, 0, prefix_len + 1);
+#endif
       else
 	return scm_dot_string;
     }
-- 
2.9.0.windows.1

>From f55f1e8de40b38cc745a930bf5a374c73d3c67ce Mon Sep 17 00:00:00 2001
From: Eli Zaretskii <e...@gnu.org>
Date: Sat, 16 Jul 2016 14:22:06 +0300
Subject: [PATCH] Fix 'strftime' for MS-Windows

* libguile/stime.c (scm_strftime) [__MINGW32__]: Don't use the
trick of appending "0" to the time-zone string, Windows runtime
doesn't support that.
---
 libguile/stime.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/libguile/stime.c b/libguile/stime.c
index 7e6f303..745b50a 100644
--- a/libguile/stime.c
+++ b/libguile/stime.c
@@ -678,6 +678,10 @@ SCM_DEFINE (scm_strftime, "strftime", 2, 0, 0,
 
   tbuf = scm_malloc (size);
   {
+#ifndef __MINGW32__
+    /* Don't do this for MinGW: it only supports fixed-format
+       TTTnnnDDD TZ specifications, and gets confused if a zero is
+       appended.  */
 #if !defined (HAVE_TM_ZONE)
     /* it seems the only way to tell non-GNU versions of strftime what
        zone to use (for the %Z format) is to set TZ in the
@@ -702,6 +706,7 @@ SCM_DEFINE (scm_strftime, "strftime", 2, 0, 0,
 	oldenv = setzone (zone, SCM_ARG2, FUNC_NAME);
       }
 #endif
+#endif
 
 #ifdef LOCALTIME_CACHE
     tzset ();
@@ -716,6 +721,7 @@ SCM_DEFINE (scm_strftime, "strftime", 2, 0, 0,
 	tbuf = scm_malloc (size);
       }
 
+#ifndef __MINGW32__
 #if !defined (HAVE_TM_ZONE)
     if (have_zone)
       {
@@ -723,6 +729,7 @@ SCM_DEFINE (scm_strftime, "strftime", 2, 0, 0,
 	SCM_CRITICAL_SECTION_END;
       }
 #endif
+#endif
     }
 
   result = scm_from_utf8_string (tbuf + 1);
-- 
2.9.0.windows.1

Reply via email to