> From: l...@gnu.org (Ludovic Courtès) > Cc: guile-devel@gnu.org > Date: Tue, 01 Jul 2014 17:38:04 +0200 > > Eli Zaretskii <e...@gnu.org> skribis: > > >> From: l...@gnu.org (Ludovic Courtès) > >> Cc: guile-devel@gnu.org > >> Date: Tue, 01 Jul 2014 11:36:32 +0200 > >> > >> Eli Zaretskii <e...@gnu.org> skribis: > >> > >> > In Emacs, some of the file and directory names recorded during the > >> > build and startup come from argv[0] and from prefix-relative directory > >> > names computed by configure. Is there something similar in Guile, and > >> > if so, where do I find that? > >> > >> The default %load-path uses absolute directory names based on what > >> ./configure computed. > > > > Thanks. Where do I find the code which does that? I'd like to review > > it with the issue at hand in mind. > > 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.) --- libguile/load.c~0 2014-02-28 23:01:27 +0200 +++ libguile/load.c 2014-07-02 19:00:50 +0300 @@ -277,6 +277,37 @@ SCM_DEFINE (scm_parse_path_with_ellipsis } #undef FUNC_NAME +static char * +getenv_path (const char *name) +{ + char *val = getenv (name); + +#ifdef __MINGW32__ + if (val) + { + char *p = val; + + /* Replace backslashes with 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 + this destructively modifies the environment variables, so + both scm_getenv and subprocesses will see the values with + forward slashes. But that is OK, since these variables are + Guile-specific, and having scm_getenv return the same value + as used by the callers of getenv_path is good for + consistency and file-name comparison. */ + while (*p) + { + if (*p == '\\') + *p = '/'; + p++; + } + } +#endif + + return val; +} /* Initialize the global variable %load-path, given the value of the SCM_SITE_DIR and SCM_LIBRARY_DIR preprocessor symbols and the @@ -289,7 +320,7 @@ scm_init_load_path () SCM cpath = SCM_EOL; #ifdef SCM_LIBRARY_DIR - env = getenv ("GUILE_SYSTEM_PATH"); + env = getenv_path ("GUILE_SYSTEM_PATH"); if (env && strcmp (env, "") == 0) /* special-case interpret system-path=="" as meaning no system path instead of '("") */ @@ -302,7 +333,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 = getenv_path ("GUILE_SYSTEM_COMPILED_PATH"); if (env && strcmp (env, "") == 0) /* like above */ ; @@ -345,14 +376,30 @@ scm_init_load_path () cachedir[0] = 0; if (cachedir[0]) - *scm_loc_compile_fallback_path = scm_from_locale_string (cachedir); + { +#ifdef __MINGW32__ + /* We don't use getenv_path for FALLBACK_DIR because those + variables are not Guile-specific, so we want to leave them + intact in the environment. This is especially relevant for + LOCALAPPDATA and APPDATA. */ + char *p = cachedir; + + while (*p) + { + if (*p == '\\') + *p = '/'; + p++; + } +#endif + *scm_loc_compile_fallback_path = scm_from_locale_string (cachedir); + } } - env = getenv ("GUILE_LOAD_PATH"); + env = getenv_path ("GUILE_LOAD_PATH"); if (env) path = scm_parse_path_with_ellipsis (scm_from_locale_string (env), path); - env = getenv ("GUILE_LOAD_COMPILED_PATH"); + env = getenv_path ("GUILE_LOAD_COMPILED_PATH"); if (env) cpath = scm_parse_path_with_ellipsis (scm_from_locale_string (env), cpath); @@ -452,11 +499,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 +923,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/filesys.c~0 2014-02-28 23:01:27 +0200 +++ libguile/filesys.c 2014-06-29 18:13:30 +0300 @@ -1235,6 +1235,19 @@ SCM_DEFINE (scm_getcwd, "getcwd", 0, 0, errno = save_errno; SCM_SYSERROR; } +#ifdef __MINGW32__ + if (rv) + { + char *p = wd; + + while (*p) + { + if (*p == '\\') + *p = '/'; + p++; + } + } +#endif result = scm_from_locale_stringn (wd, strlen (wd)); free (wd); return result; --- module/ice-9/boot-9.scm~ 2014-02-15 01:00:33 +0200 +++ module/ice-9/boot-9.scm 2014-06-29 18: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) --- libguile/init.c~0 2014-02-28 23:01:27 +0200 +++ libguile/init.c 2014-07-02 18:51:04 +0300 @@ -310,6 +310,17 @@ scm_boot_guile (int argc, char ** argv, { void *res; struct main_func_closure c; +#ifdef __MINGW32__ + /* Convert backslashes in argv[0] to forward slashes. */ + char *p = argv[0]; + + while (*p) + { + if (*p == '\\') + *p = '/'; + p++; + } +#endif c.main_func = main_func; c.closure = closure;