> 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