diff --git a/racket/src/Makefile.in b/racket/src/Makefile.in index e15d1367b9..7870fa0e60 100644 --- a/racket/src/Makefile.in +++ b/racket/src/Makefile.in @@ -255,7 +255,7 @@ clean: SRC_MAKEFILES = $(srcdir)/Makefile.in $(srcdir)/racket/Makefile.in \ $(srcdir)/racket/src/Makefile.in $(srcdir)/gracket/Makefile.in \ $(srcdir)/racket/gc2/Makefile.in $(srcdir)/gracket/gc2/Makefile.in \ - $(srcdir)/racket/dynsrc/Makefile.in + $(srcdir)/rktio/Makefile.in $(srcdir)/racket/dynsrc/Makefile.in reconfigure: $(MAKE) Makefile diff --git a/racket/src/foreign/foreign.c b/racket/src/foreign/foreign.c index ad7a61e060..56abd8587d 100644 --- a/racket/src/foreign/foreign.c +++ b/racket/src/foreign/foreign.c @@ -263,8 +263,11 @@ static Scheme_Object *foreign_ffi_lib(int argc, Scheme_Object *argv[]) /* openning the executable is marked by a NULL handle */ handle = NULL; null_ok = 1; - } else - handle = LoadLibraryW(WIDE_PATH(name)); + } else { + wchar_t *wp; + wp = scheme_path_to_wide_path(MYNAME, name); + handle = LoadLibraryW(wp); + } # else /* WINDOWS_DYNAMIC_LOAD undefined */ # ifdef __ANDROID__ if (!name) handle = RTLD_DEFAULT; else diff --git a/racket/src/foreign/foreign.rktc b/racket/src/foreign/foreign.rktc index cab6fea4df..6f3771bade 100755 --- a/racket/src/foreign/foreign.rktc +++ b/racket/src/foreign/foreign.rktc @@ -233,8 +233,11 @@ THREAD_LOCAL_DECL(static Scheme_Hash_Table *opened_libs); /* openning the executable is marked by a NULL handle */ handle = NULL; null_ok = 1; - } else - handle = LoadLibraryW(WIDE_PATH(name)); + } else { + wchar_t *wp; + wp = scheme_path_to_wide_path(MYNAME, name); + handle = LoadLibraryW(wp); + } }{ @@IFDEF{__ANDROID__}{if (!name) handle = RTLD_DEFAULT; else} @@IFDEF{__CYGWIN32__}{if (!name) { handle = RTLD_DEFAULT; null_ok = 1; } else} diff --git a/racket/src/racket/src/dynext.c b/racket/src/racket/src/dynext.c index ab8076aa14..83fe54f7e8 100644 --- a/racket/src/racket/src/dynext.c +++ b/racket/src/racket/src/dynext.c @@ -299,16 +299,18 @@ static Scheme_Object *do_load_extension(const char *filename, HINSTANCE dl; Setup_Procedure f; char *vers; - - dl = LoadLibraryW(WIDE_PATH(filename)); + wchar_t *wp; + + wp = scheme_path_to_wide_path(NULL, filename); + dl = LoadLibraryW(wp); if (!dl) { long err; err = GetLastError(); scheme_raise_exn(MZEXN_FAIL_FILESYSTEM, - "load-extension: could not load file\n" + "load-extension: could not load file\n" " path: %q\n" " system error: %E", - filename, err); + filename, err); } handle = (void *)dl; diff --git a/racket/src/racket/src/file.c b/racket/src/racket/src/file.c index e695e90e73..261c32d46e 100644 --- a/racket/src/racket/src/file.c +++ b/racket/src/racket/src/file.c @@ -1049,62 +1049,38 @@ int scheme_os_setcwd(char *expanded, int noexn) } #ifdef DOS_FILE_SYSTEM -#define WC_BUFFER_SIZE 1024 -THREAD_LOCAL_DECL(static void *file_path_wc_buffer); -static int wc_strlen(const wchar_t *ws) +static intptr_t wc_strlen(const wchar_t *ws) { - int l; + intptr_t l; for (l =0; ws[l]; l++) { } return l; } -wchar_t *scheme_convert_to_wchar(const char *s, int do_copy) - /* This function uses '\t' in place of invalid UTF-8 encoding - bytes, because '\t' is not a legal filename under Windows. */ +wchar_t *scheme_path_to_wide_path(const char *who, const char *p) { - intptr_t len, l; - wchar_t *ws; + wchar_t *wp, *gc_wp; + intptr_t len; + + wp = rktio_path_to_wide_path(scheme_rktio, p); + if (wp) { + len = wc_strlen(wp); + gc_wp = scheme_malloc_atomic((len + 1) * sizeof(wchar_t)); + memcpy(gc_wp, wp, (len + 1) * sizeof(wchar_t)); + free(wp); + return gc_wp; + } + if (who) + scheme_raise_exn(MZEXN_FAIL_FILESYSTEM, + "%s: could not read file\n" + " path: %q\n" + " system error: %R", + p); - l = strlen(s); - len = scheme_utf8_decode(s, 0, l, - NULL, 0, -1, - NULL, 1/*UTF-16*/, '\t'); - - if (!do_copy && (len < (WC_BUFFER_SIZE-1))) { - if (!file_path_wc_buffer) { - REGISTER_SO(file_path_wc_buffer); - file_path_wc_buffer = scheme_malloc_atomic(sizeof(wchar_t) * WC_BUFFER_SIZE); - } - ws = (wchar_t *)file_path_wc_buffer; - } else - ws = (wchar_t *)scheme_malloc_atomic(sizeof(wchar_t) * (len + 1)); - scheme_utf8_decode(s, 0, l, - (unsigned int *)ws, 0, -1, - NULL, 1/*UTF-16*/, '\t'); - ws[len] = 0; - return ws; -} - -char *scheme_convert_from_wchar(const wchar_t *ws) -{ - intptr_t len, l; - char *s; - - l = wc_strlen(ws); - len = scheme_utf8_encode((unsigned int *)ws, 0, l, - NULL, 0, - 1/*UTF-16*/); - s = (char *)scheme_malloc_atomic(len + 1); - scheme_utf8_encode((unsigned int *)ws, 0, l, - s, 0, - 1/*UTF-16*/); - s[len] = 0; - return s; + return NULL; } #endif - Scheme_Object *scheme_get_file_directory(const char *filename) { int isdir; diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index 0eee605d70..671bd30a48 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -4241,25 +4241,7 @@ Scheme_Object *scheme_extract_relative_to(Scheme_Object *obj, Scheme_Object *dir Scheme_Object *scheme_find_links_path(int argc, Scheme_Object *argv[]); #ifdef DOS_FILE_SYSTEM -# define WIDE_PATH(s) scheme_convert_to_wchar(s, 0) -# define WIDE_PATH_COPY(s) scheme_convert_to_wchar(s, 1) -# define NARROW_PATH(s) scheme_convert_from_wchar(s) -extern wchar_t *scheme_convert_to_wchar(const char *s, int do_copy); -extern char *scheme_convert_from_wchar(const wchar_t *ws); -#else -# define WIDE_PATH(s) s -# define WIDE_PATH_COPY(s) s -# define NARROW_PATH(s) s -#endif - -#if defined(DOS_FILE_SYSTEM) && !defined(__CYGWIN32__) -# define MSC_W_IZE(n) _w ## n -# define MSC_WIDE_PATH(s) WIDE_PATH(s) -# define MSC_WIDE_PATH_COPY(s) WIDE_PATH_COPY(s) -#else -# define MSC_W_IZE(n) MSC_IZE(n) -# define MSC_WIDE_PATH(s) s -# define MSC_WIDE_PATH_COPY(s) s +wchar_t *scheme_path_to_wide_path(const char *who, const char *p); #endif /*========================================================================*/ diff --git a/racket/src/rktio/rktio.h b/racket/src/rktio/rktio.h index f9626a0065..56fca913ce 100644 --- a/racket/src/rktio/rktio.h +++ b/racket/src/rktio/rktio.h @@ -872,9 +872,19 @@ rktio_ok_t rktio_shell_execute(rktio_t *rktio, const char *arg, const char *dir, int show_mode); -/* Support only on Windows to run `ShellExecute`. The `dir` argument +/* Supported only on Windows to run `ShellExecute`. The `dir` argument needs to have normalized path separators. */ +/*************************************************/ +/* Path conversion */ + +void *rktio_path_to_wide_path(rktio_t *rktio, const char *p); +char *rktio_wide_path_to_path(rktio_t *rktio, const void *wp); +/* Convert to/from the OS's native path representation. These + functions are useful only on Windows, where each `void *` + is actually a `wchar_t*`. The `rktio_path_to_wide_path` + function can fail and report `RKTIO_ERROR_INVALID_PATH`. */ + /*************************************************/ /* Errors */ diff --git a/racket/src/rktio/rktio_wide.c b/racket/src/rktio/rktio_wide.c index 9be43f6b01..fb72092d55 100644 --- a/racket/src/rktio/rktio_wide.c +++ b/racket/src/rktio/rktio_wide.c @@ -5,6 +5,17 @@ #ifdef RKTIO_SYSTEM_UNIX void rktio_init_wide(rktio_t *rktio) { } + +void *rktio_path_to_wide_path(rktio_t *rktio, const char *p) +{ + return strdup(p); +} + +char *rktio_wide_path_to_path(rktio_t *rktio, const void *wp) +{ + return strdup((char *)wp); +} + #endif #ifdef RKTIO_SYSTEM_WINDOWS @@ -308,4 +319,14 @@ char *rktio_convert_from_wchar(const wchar_t *ws, int free_given) return s; } +void *rktio_path_to_wide_path(rktio_t *rktio, const char *p) +{ + return WIDE_PATH_copy(p); +} + +char *rktio_wide_path_to_path(rktio_t *rktio, const void *wp) +{ + return NARROW_PATH_copy(wp); +} + #endif