From: Eli Zaretskii <eliz@gnu.org>
To: ludo@gnu.org (Ludovic Courtès)
Cc: guile-devel@gnu.org
Subject: Re: Windows file name separators
Date: Thu, 03 Jul 2014 18:10:28 +0300 [thread overview]
Message-ID: <83d2dm32cb.fsf@gnu.org> (raw)
In-Reply-To: <87a98rfph6.fsf@gnu.org>
> From: ludo@gnu.org (Ludovic Courtès)
> Cc: guile-devel@gnu.org
> Date: Wed, 02 Jul 2014 22:57:41 +0200
>
> Eli Zaretskii <eliz@gnu.org> skribis:
>
> >> From: ludo@gnu.org (Ludovic Courtès)
> >> Cc: guile-devel@gnu.org
> >> Date: Tue, 01 Jul 2014 17:38:04 +0200
>
> [...]
>
> >> You can look at load.c, and in particular scm_init_load_path.
> >
> > OK, thanks for the pointer.
> >
> > I've reviewed the related code, and below is what I suggest to push.
> > (This supersedes what I sent in
> > http://lists.gnu.org/archive/html/guile-devel/2014-06/msg00066.html.)
>
> Also, could you add tests for that? Namely, a ‘search-path’ use that
> currently returns a file name with backslashes, and will now return a
> file name with forward slashes.
Is the below OK?
--- libguile/load.c~0 2014-02-28 23:01:27 +0200
+++ libguile/load.c 2014-07-03 09:58:29 +0300
@@ -277,6 +277,41 @@ SCM_DEFINE (scm_parse_path_with_ellipsis
}
#undef FUNC_NAME
+/* On Posix hosts, just return PATH unaltered. On Windows,
+ destructively replace all backslashes in PATH with Unix-style
+ forward slashes, so that Scheme code always gets d:/foo/bar style
+ file names. This avoids multiple subtle problems with comparing
+ file names as strings, and with redirections in /bin/sh command
+ lines.
+
+ Note that, if PATH is result of a call to 'getenv', this
+ destructively modifies the environment variables, so both
+ scm_getenv and subprocesses will afterwards see the values with
+ forward slashes. That is OK as long as applied to Guile-specific
+ environment variables, since having scm_getenv return the same
+ value as used by the callers of this function is good for
+ consistency and file-name comparison. Avoid using this function on
+ values returned by 'getenv' for general-purpose environment
+ variables; instead, make a copy of the value and work on that. */
+SCM_INTERNAL char *
+scm_i_mirror_backslashes (char *path)
+{
+#ifdef __MINGW32__
+ if (path)
+ {
+ char *p = path;
+
+ while (*p)
+ {
+ if (*p == '\\')
+ *p = '/';
+ p++;
+ }
+ }
+#endif
+
+ return path;
+}
/* Initialize the global variable %load-path, given the value of the
SCM_SITE_DIR and SCM_LIBRARY_DIR preprocessor symbols and the
@@ -289,7 +324,7 @@ scm_init_load_path ()
SCM cpath = SCM_EOL;
#ifdef SCM_LIBRARY_DIR
- env = getenv ("GUILE_SYSTEM_PATH");
+ env = scm_i_mirror_backslashes (getenv ("GUILE_SYSTEM_PATH"));
if (env && strcmp (env, "") == 0)
/* special-case interpret system-path=="" as meaning no system path instead
of '("") */
@@ -302,7 +337,7 @@ scm_init_load_path ()
scm_from_locale_string (SCM_GLOBAL_SITE_DIR),
scm_from_locale_string (SCM_PKGDATA_DIR));
- env = getenv ("GUILE_SYSTEM_COMPILED_PATH");
+ env = scm_i_mirror_backslashes (getenv ("GUILE_SYSTEM_COMPILED_PATH"));
if (env && strcmp (env, "") == 0)
/* like above */
;
@@ -345,14 +380,17 @@ scm_init_load_path ()
cachedir[0] = 0;
if (cachedir[0])
- *scm_loc_compile_fallback_path = scm_from_locale_string (cachedir);
+ {
+ scm_i_mirror_backslashes (cachedir);
+ *scm_loc_compile_fallback_path = scm_from_locale_string (cachedir);
+ }
}
- env = getenv ("GUILE_LOAD_PATH");
+ env = scm_i_mirror_backslashes (getenv ("GUILE_LOAD_PATH"));
if (env)
path = scm_parse_path_with_ellipsis (scm_from_locale_string (env), path);
- env = getenv ("GUILE_LOAD_COMPILED_PATH");
+ env = scm_i_mirror_backslashes (getenv ("GUILE_LOAD_COMPILED_PATH"));
if (env)
cpath = scm_parse_path_with_ellipsis (scm_from_locale_string (env), cpath);
@@ -452,11 +490,10 @@ scm_c_string_has_an_ext (char *str, size
return 0;
}
-#ifdef __MINGW32__
-#define FILE_NAME_SEPARATOR_STRING "\\"
-#else
+/* Defined as "/" for Unix and Windows alike, so that file names
+ constructed by the functions in this module wind up with Unix-style
+ forward slashes as directory separators. */
#define FILE_NAME_SEPARATOR_STRING "/"
-#endif
static int
is_file_name_separator (SCM c)
@@ -877,7 +914,7 @@ canonical_suffix (SCM fname)
/* CANON should be absolute. */
canon = scm_canonicalize_path (fname);
-
+
#ifdef __MINGW32__
{
size_t len = scm_c_string_length (canon);
--- libguile/load.h~0 2013-03-19 00:30:13 +0200
+++ libguile/load.h 2014-07-03 09:59:17 +0300
@@ -44,6 +44,7 @@ SCM_INTERNAL void scm_init_load_path (vo
SCM_INTERNAL void scm_init_load (void);
SCM_INTERNAL void scm_init_load_should_auto_compile (void);
SCM_INTERNAL void scm_init_eval_in_scheme (void);
+SCM_INTERNAL char *scm_i_mirror_backslashes (char *path);
#endif /* SCM_LOAD_H */
--- libguile/filesys.c~0 2014-02-28 23:01:27 +0200
+++ libguile/filesys.c 2014-07-03 10:03:25 +0300
@@ -51,6 +51,7 @@
#include "libguile/validate.h"
#include "libguile/filesys.h"
+#include "libguile/load.h" /* for scm_i_mirror_backslashes */
\f
#ifdef HAVE_IO_H
@@ -1235,6 +1248,9 @@ SCM_DEFINE (scm_getcwd, "getcwd", 0, 0,
errno = save_errno;
SCM_SYSERROR;
}
+ /* On Windows, convert backslashes in current directory to forward
+ slashes. */
+ scm_i_mirror_backslashes (wd);
result = scm_from_locale_stringn (wd, strlen (wd));
free (wd);
return result;
--- libguile/init.c~0 2014-02-28 23:01:27 +0200
+++ libguile/init.c 2014-07-03 10:02:03 +0300
@@ -311,6 +311,9 @@ scm_boot_guile (int argc, char ** argv,
void *res;
struct main_func_closure c;
+ /* On Windows, convert backslashes in argv[0] to forward
+ slashes. */
+ scm_i_mirror_backslashes (argv[0]);
c.main_func = main_func;
c.closure = closure;
c.argc = argc;
--- module/ice-9/boot-9.scm~ 2014-02-15 01:00:33 +0200
+++ module/ice-9/boot-9.scm 2014-06-29 16:15:07 +0300
@@ -1657,7 +1657,7 @@
(or (char=? c #\/)
(char=? c #\\)))
- (define file-name-separator-string "\\")
+ (define file-name-separator-string "/")
(define (absolute-file-name? file-name)
(define (file-name-separator-at-index? idx)
--- test-suite/tests/ports.test~2 2014-06-29 16:06:51 +0300
+++ test-suite/tests/ports.test 2014-07-03 10:55:30 +0300
@@ -1866,6 +1865,17 @@
(with-fluids ((%file-port-name-canonicalization 'absolute))
(port-filename (open-input-file (%search-load-path "ice-9/q.scm"))))))
+(with-test-prefix "file name separators"
+
+ (pass-if "no backslash separators in Windows file names"
+ ;; In Guile 2.0.11 and earlier, %load-path on Windows could
+ ;; include file names with backslashes, and `getcwd' on Windows
+ ;; would always return a directory name with backslashes.
+ (or (not (file-name-separator? #\\))
+ (with-load-path (cons (getcwd) %load-path)
+ (not (string-index (%search-load-path (basename (test-file)))
+ #\\))))))
+
(delete-file (test-file))
;;; Local Variables:
next prev parent reply other threads:[~2014-07-03 15:10 UTC|newest]
Thread overview: 65+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-08 15:04 MinGW issues in Guile 2.0.11 Eli Zaretskii
2014-06-09 15:47 ` Eli Zaretskii
2014-06-09 18:01 ` Mark H Weaver
2014-06-09 18:25 ` Eli Zaretskii
2014-06-09 19:30 ` MinGW vs. setlocale Ludovic Courtès
2014-06-10 16:17 ` Eli Zaretskii
2014-06-11 13:13 ` Ludovic Courtès
2014-06-11 15:33 ` Eli Zaretskii
2014-06-12 8:39 ` Ludovic Courtès
2014-06-12 18:18 ` Eli Zaretskii
2014-06-15 17:23 ` Eli Zaretskii
2014-06-21 11:17 ` Eli Zaretskii
2014-06-21 15:02 ` Ludovic Courtès
2014-06-21 15:11 ` Eli Zaretskii
2014-06-21 21:23 ` Ludovic Courtès
2014-06-22 16:13 ` Eli Zaretskii
2014-06-19 4:53 ` Doug Evans
2014-06-19 8:16 ` Ludovic Courtès
2014-06-09 19:32 ` MinGW vs. c-api.test Ludovic Courtès
2014-06-10 9:05 ` Neil Jerram
2014-06-10 11:42 ` Ludovic Courtès
2014-06-10 15:32 ` Eli Zaretskii
2014-06-10 15:56 ` David Kastrup
2014-06-10 18:00 ` Eli Zaretskii
2014-06-11 0:36 ` dsmich
2014-06-11 2:52 ` Eli Zaretskii
2014-06-10 11:44 ` Ludovic Courtès
2014-06-10 15:39 ` Eli Zaretskii
2014-06-11 12:37 ` Ludovic Courtès
2014-06-11 15:08 ` Eli Zaretskii
2014-06-12 8:29 ` Ludovic Courtès
2014-06-12 17:16 ` Eli Zaretskii
2014-06-12 19:48 ` Ludovic Courtès
2014-06-12 19:59 ` Eli Zaretskii
2014-06-12 21:20 ` Ludovic Courtès
2014-06-13 9:15 ` Neil Jerram
2014-06-13 16:04 ` Ludovic Courtès
2014-06-13 16:19 ` Eli Zaretskii
2014-06-13 16:26 ` Neil Jerram
2014-06-13 16:31 ` Mike Gerwitz
2014-06-13 18:09 ` Eli Zaretskii
2014-06-09 19:42 ` Windows file name separators Ludovic Courtès
2014-06-10 16:00 ` Eli Zaretskii
2014-06-30 11:15 ` Ludovic Courtès
2014-06-30 14:56 ` Eli Zaretskii
2014-07-01 9:36 ` Ludovic Courtès
2014-07-01 15:30 ` Eli Zaretskii
2014-07-01 15:38 ` Ludovic Courtès
2014-07-02 16:04 ` Eli Zaretskii
2014-07-02 20:56 ` Ludovic Courtès
2014-07-02 20:57 ` Ludovic Courtès
2014-07-03 15:10 ` Eli Zaretskii [this message]
2014-07-03 17:11 ` Ludovic Courtès
2014-07-03 18:09 ` Eli Zaretskii
2014-07-07 20:53 ` Mark H Weaver
2014-07-08 2:37 ` Eli Zaretskii
2014-07-02 16:13 ` Fix 'dirname' and 'basename' on MS-Windows Eli Zaretskii
2014-07-09 14:22 ` Ludovic Courtès
2014-07-09 14:53 ` Eli Zaretskii
2014-07-02 16:16 ` Provide reasonable stack limit " Eli Zaretskii
2014-07-02 21:02 ` Ludovic Courtès
2014-07-03 16:28 ` Eli Zaretskii
2014-07-02 16:30 ` Bug in scm_getaffinity Eli Zaretskii
2014-07-02 21:04 ` Ludovic Courtès
2014-07-03 16:31 ` Eli Zaretskii
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/guile/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=83d2dm32cb.fsf@gnu.org \
--to=eliz@gnu.org \
--cc=guile-devel@gnu.org \
--cc=ludo@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).