rktio: add Windows path conversion functions

This commit is contained in:
Matthew Flatt 2017-06-20 21:13:36 -06:00
parent 898b9ffe10
commit 69a208eb21
8 changed files with 71 additions and 74 deletions

View File

@ -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

View File

@ -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

View File

@ -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}

View File

@ -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;

View File

@ -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;

View File

@ -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
/*========================================================================*/

View File

@ -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 */

View File

@ -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