[m-rev.] for review: move some conversion functions into the runtime.
Julien Fischer
jfischer at opturion.com
Mon Oct 16 00:51:18 AEDT 2023
For review by anyone.
The upcoming changes referred to below are related the creation of
trace count files and also the program-specific Mercury options on
Windows.
--------------------------------------
Move some conversion functions into the runtime.
Move the functions that convert between the UTF-8 and wide encodings of a
string on Windows from the library into the runtime. Upcoming changes will
require their presence in the runtime.
library/io.m:
Move ML_utf8_to_wide() and ML_wide_to_utf8() from here ...
runtime/mercury_string.[ch]:
... to here and s/ML_/MR_/.
library/dir.m:
library/io.call_system.m:
library/io.environment.m:
library/io.file.m:
library/io.stream_ops.m:
Conform to the above change.
Julien.
diff --git a/library/dir.m b/library/dir.m
index 05c5c84..ed0f43f 100644
--- a/library/dir.m
+++ b/library/dir.m
@@ -1034,7 +1034,7 @@ current_directory(Result, !IO) :-
wbuf = _wgetcwd(NULL, 1);
if (wbuf != NULL) {
- CurDir = ML_wide_to_utf8(wbuf, MR_ALLOC_ID);
+ CurDir = MR_wide_to_utf8(wbuf, MR_ALLOC_ID);
Error = 0;
free(wbuf);
} else {
@@ -1306,7 +1306,7 @@ make_single_directory(DirName, Result, !IO) :-
will_not_modify_trail, does_not_affect_liveness, may_not_duplicate],
"
#if defined(MR_WIN32)
- if (CreateDirectoryW(ML_utf8_to_wide(DirName), NULL)) {
+ if (CreateDirectoryW(MR_utf8_to_wide(DirName), NULL)) {
Status = ML_MAKE_SINGLE_DIRECTORY_OK;
Error = 0;
} else {
@@ -1777,7 +1777,7 @@ open_2(DirName, DirPattern, Result, !IO) :-
DirStream = MR_GC_NEW_ATTRIB(struct ML_DIR_STREAM, MR_ALLOC_ID);
- DirStream->handle = FindFirstFileW(ML_utf8_to_wide(DirPattern), &file_data);
+ DirStream->handle = FindFirstFileW(MR_utf8_to_wide(DirPattern), &file_data);
if (DirStream->handle == INVALID_HANDLE_VALUE) {
Error = GetLastError();
if (Error == ERROR_NO_MORE_FILES) {
@@ -1786,7 +1786,7 @@ open_2(DirName, DirPattern, Result, !IO) :-
DirStream->pending_entry = NULL;
} else {
Error = 0;
- DirStream->pending_entry = ML_wide_to_utf8(file_data.cFileName, MR_ALLOC_ID);
+ DirStream->pending_entry = MR_wide_to_utf8(file_data.cFileName, MR_ALLOC_ID);
}
IsWin32Error = MR_YES;
@@ -2031,7 +2031,7 @@ read_entry(DirStream, Result, !IO) :-
Error = 0;
IsWin32Error = MR_YES;
HaveFileName = MR_YES;
- FileName = ML_wide_to_utf8(file_data.cFileName, MR_ALLOC_ID);
+ FileName = MR_wide_to_utf8(file_data.cFileName, MR_ALLOC_ID);
} else {
Error = GetLastError();
IsWin32Error = MR_YES;
diff --git a/library/io.call_system.m b/library/io.call_system.m
index ef23c49..7bd5b96 100644
--- a/library/io.call_system.m
+++ b/library/io.call_system.m
@@ -2,7 +2,7 @@
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 1993-2012 The University of Melbourne.
-% Copyright (C) 2013-2022 The Mercury team.
+% Copyright (C) 2013-2023 The Mercury team.
% This file is distributed under the terms specified in COPYING.LIB.
%---------------------------------------------------------------------------%
%
@@ -53,6 +53,14 @@
%---------------------------------------------------------------------------%
+:- pragma foreign_decl("C", "
+#if defined(MR_WIN32)
+ #include ""mercury_string.h"" // For MR_utf8_to_wide.
+#endif
+").
+
+%---------------------------------------------------------------------------%
+
call_system(Command, Result, !IO) :-
io.call_system.call_system_return_signal(Command, Result0, !IO),
(
@@ -143,7 +151,7 @@ call_system_return_signal(Command, Result, !IO) :-
#else // !MR_THREAD_SAFE || !MR_HAVE_POSIX_SPAWN || !MR_HAVE_ENVIRON
#ifdef MR_WIN32
- Status = _wsystem(ML_utf8_to_wide(Command));
+ Status = _wsystem(MR_utf8_to_wide(Command));
#else
Status = system(Command);
#endif
diff --git a/library/io.environment.m b/library/io.environment.m
index c16d83c..28354aa 100644
--- a/library/io.environment.m
+++ b/library/io.environment.m
@@ -70,6 +70,14 @@
%---------------------------------------------------------------------------%
+:- pragma foreign_decl("C", "
+#if defined(MR_WIN32)
+ #include ""mercury_string.h"" // For MR_utf8_to_wide.
+#endif
+").
+
+%---------------------------------------------------------------------------%
+
get_environment_var(Var, OptValue, !IO) :-
promise_pure (
( if semipure getenv(Var, Value) then
@@ -272,9 +280,9 @@ record_env_var_and_value(EnvVarName, EnvVarValue, !EnvVarAL) :-
does_not_affect_liveness, no_sharing],
"
#ifdef MR_WIN32
- wchar_t *ValueW = _wgetenv(ML_utf8_to_wide(Var));
+ wchar_t *ValueW = _wgetenv(MR_utf8_to_wide(Var));
if (ValueW != NULL) {
- Value = ML_wide_to_utf8(ValueW, MR_ALLOC_ID);
+ Value = MR_wide_to_utf8(ValueW, MR_ALLOC_ID);
} else {
Value = NULL;
}
@@ -315,7 +323,7 @@ record_env_var_and_value(EnvVarName, EnvVarValue, !EnvVarAL) :-
"
#ifdef MR_WIN32
SUCCESS_INDICATOR =
- (_wputenv_s(ML_utf8_to_wide(Var), ML_utf8_to_wide(Value)) == 0);
+ (_wputenv_s(MR_utf8_to_wide(Var), MR_utf8_to_wide(Value)) == 0);
#else
SUCCESS_INDICATOR = (setenv(Var, Value, 1) == 0);
#endif
diff --git a/library/io.file.m b/library/io.file.m
index 6de7b4c..3bf535c 100644
--- a/library/io.file.m
+++ b/library/io.file.m
@@ -240,7 +240,7 @@ remove_file(FileName, Result, !IO) :-
int rc;
#ifdef MR_WIN32
// XXX _wremove will not delete an empty directory; _wrmdir does that.
- rc = _wremove(ML_utf8_to_wide(FileName));
+ rc = _wremove(MR_utf8_to_wide(FileName));
#else
rc = remove(FileName);
#endif
@@ -375,8 +375,8 @@ rename_file(OldFileName, NewFileName, Result, !IO) :-
"
int rc;
#ifdef MR_WIN32
- rc = _wrename(ML_utf8_to_wide(OldFileName),
- ML_utf8_to_wide(NewFileName));
+ rc = _wrename(MR_utf8_to_wide(OldFileName),
+ MR_utf8_to_wide(NewFileName));
#else
rc = rename(OldFileName, NewFileName);
#endif
@@ -661,7 +661,7 @@ check_file_accessibility(FileName, AccessTypes, Result, !IO) :-
}
#ifdef MR_WIN32
- access_result = _waccess(ML_utf8_to_wide(FileName), mode);
+ access_result = _waccess(MR_utf8_to_wide(FileName), mode);
#else
access_result = access(FileName, mode);
#endif
@@ -848,7 +848,7 @@ file_type(FollowSymLinks, FileName, Result, !IO) :-
#ifdef MR_HAVE_STAT
#ifdef MR_WIN32
struct _stat s;
- int stat_result = _wstat(ML_utf8_to_wide(FileName), &s);
+ int stat_result = _wstat(MR_utf8_to_wide(FileName), &s);
#else
struct stat s;
int stat_result;
@@ -1064,7 +1064,7 @@ file_modification_time(File, Result, !IO) :-
#ifdef MR_HAVE_STAT
#ifdef MR_WIN32
struct _stat s;
- int stat_result = _wstat(ML_utf8_to_wide(FileName), &s);
+ int stat_result = _wstat(MR_utf8_to_wide(FileName), &s);
#else
struct stat s;
int stat_result = stat(FileName, &s);
@@ -1215,7 +1215,7 @@ make_temp_file(Dir, Prefix, Suffix, Result, !IO) :-
flags = O_WRONLY | O_CREAT | O_EXCL;
do {
#ifdef MR_WIN32
- fd = _wopen(ML_utf8_to_wide(FileName), flags, 0600);
+ fd = _wopen(MR_utf8_to_wide(FileName), flags, 0600);
#else
fd = open(FileName, flags, 0600);
#endif
@@ -1435,6 +1435,9 @@ make_temp_directory(ParentDirName, Prefix, Suffix, Result, !IO) :-
%---------------------%
:- pragma foreign_decl("C", "
+#ifdef MR_WIN32
+ #include ""mercury_string.h"" // For MR_ut8_to_wide.
+#endif
#ifdef MR_HAVE_UNISTD_H
#include <unistd.h>
#endif
diff --git a/library/io.m b/library/io.m
index e2c91a5..f921115 100644
--- a/library/io.m
+++ b/library/io.m
@@ -6035,11 +6035,6 @@ extern MR_Word ML_io_user_globals;
void mercury_init_io(void);
-#ifdef MR_WIN32
- wchar_t *ML_utf8_to_wide(const char *s);
- char *ML_wide_to_utf8(const wchar_t *ws,
- MR_AllocSiteInfoPtr alloc_id);
-#endif
").
:- pragma foreign_code("C", "
@@ -6116,46 +6111,6 @@ mercury_init_io(void)
pthread_mutex_init(&ML_io_next_stream_id_lock, MR_MUTEX_ATTR);
#endif
}
-
-#ifdef MR_WIN32
-
-// Accessing Unicode file names on Windows requires that we use the functions
-// taking wide character strings.
-wchar_t *
-ML_utf8_to_wide(const char *s)
-{
- int wslen;
- wchar_t *ws;
-
- wslen = MultiByteToWideChar(CP_UTF8, 0, s, -1, NULL, 0);
- if (wslen == 0) {
- MR_fatal_error(""ML_utf8_to_wide: MultiByteToWideChar failed"");
- }
- ws = MR_GC_NEW_ARRAY(wchar_t, wslen);
- if (0 == MultiByteToWideChar(CP_UTF8, 0, s, -1, ws, wslen)) {
- MR_fatal_error(""ML_utf8_to_wide: MultiByteToWideChar failed"");
- }
- return ws;
-}
-
-char *
-ML_wide_to_utf8(const wchar_t *ws, MR_AllocSiteInfoPtr alloc_id)
-{
- char *s;
- int bytes;
-
- bytes = WideCharToMultiByte(CP_UTF8, 0, ws, -1, NULL, 0, NULL, NULL);
- if (bytes == 0) {
- MR_fatal_error(""ML_wide_to_utf8: WideCharToMultiByte failed"");
- }
- MR_allocate_aligned_string_msg(s, bytes, alloc_id);
- if (0 == WideCharToMultiByte(CP_UTF8, 0, ws, -1, s, bytes, NULL, NULL)) {
- MR_fatal_error(""ML_wide_to_utf8: WideCharToMultiByte failed"");
- }
- return s;
-}
-
-#endif // MR_WIN32
").
%---------------------%
diff --git a/library/io.stream_ops.m b/library/io.stream_ops.m
index 07c47d3..f0902eb 100644
--- a/library/io.stream_ops.m
+++ b/library/io.stream_ops.m
@@ -875,6 +875,11 @@ stderr_stream_2(Stream, !IO) :-
%---------------------------------------------------------------------------%
:- pragma foreign_decl("C", "
+
+#if defined(MR_WIN32)
+ #include ""mercury_string.h"" // For MR_utf8_to_wide.
+#endif
+
extern MercuryFile mercury_stdin;
extern MercuryFile mercury_stdout;
extern MercuryFile mercury_stderr;
@@ -976,7 +981,7 @@ mercury_open(const char *filename, const char *openmode,
FILE *f;
#ifdef MR_WIN32
- f = _wfopen(ML_utf8_to_wide(filename), ML_utf8_to_wide(openmode));
+ f = _wfopen(MR_utf8_to_wide(filename), MR_utf8_to_wide(openmode));
#else
f = fopen(filename, openmode);
#endif
diff --git a/runtime/mercury_string.c b/runtime/mercury_string.c
index 7492a69..a5e20a7 100644
--- a/runtime/mercury_string.c
+++ b/runtime/mercury_string.c
@@ -1,13 +1,14 @@
// vim: ts=4 sw=4 expandtab ft=c
// Copyright (C) 2000-2002, 2006, 2011-2012 The University of Melbourne.
-// Copyright (C) 2015-2016, 2018-2019 The Mercury team.
+// Copyright (C) 2015-2016, 2018-2019, 2023 The Mercury team.
// This file is distributed under the terms specified in COPYING.LIB.
// mercury_string.c - string handling
#include "mercury_imp.h"
#include "mercury_string.h"
+#include "mercury_windows.h"
#ifdef _MSC_VER
// Disable warnings about using _vsnprintf being deprecated.
@@ -574,3 +575,39 @@ MR_utf8_find_ill_formed_char(const MR_String s)
}
}
}
+
+#if defined(MR_WIN32)
+wchar_t *
+MR_utf8_to_wide(const char *s)
+{
+ int wslen;
+ wchar_t *ws;
+
+ wslen = MultiByteToWideChar(CP_UTF8, 0, s, -1, NULL, 0);
+ if (wslen == 0) {
+ MR_fatal_error("ML_utf8_to_wide: MultiByteToWideChar failed");
+ }
+ ws = MR_GC_NEW_ARRAY(wchar_t, wslen);
+ if (0 == MultiByteToWideChar(CP_UTF8, 0, s, -1, ws, wslen)) {
+ MR_fatal_error("ML_utf8_to_wide: MultiByteToWideChar failed");
+ }
+ return ws;
+}
+
+char *
+MR_wide_to_utf8(const wchar_t *ws, MR_AllocSiteInfoPtr alloc_id)
+{
+ char *s;
+ int bytes;
+
+ bytes = WideCharToMultiByte(CP_UTF8, 0, ws, -1, NULL, 0, NULL, NULL);
+ if (bytes == 0) {
+ MR_fatal_error("ML_wide_to_utf8: WideCharToMultiByte failed");
+ }
+ MR_allocate_aligned_string_msg(s, bytes, alloc_id);
+ if (0 == WideCharToMultiByte(CP_UTF8, 0, ws, -1, s, bytes, NULL, NULL)) {
+ MR_fatal_error("ML_wide_to_utf8: WideCharToMultiByte failed");
+ }
+ return s;
+}
+#endif // MR_WIN32
diff --git a/runtime/mercury_string.h b/runtime/mercury_string.h
index 008cd83..1b28f3a 100644
--- a/runtime/mercury_string.h
+++ b/runtime/mercury_string.h
@@ -1,7 +1,7 @@
// vim: ts=4 sw=4 expandtab ft=c
// Copyright (C) 1995-2005, 2007, 2011-2012 The University of Melbourne.
-// Copyright (C) 2015-2016, 2018 The Mercury team.
+// Copyright (C) 2015-2016, 2018-2019, 2021, 2023 The Mercury team.
// This file is distributed under the terms specified in COPYING.LIB.
// mercury_string.h - string handling
@@ -14,6 +14,9 @@
#include <string.h> // for strcmp() etc.
#include <stdarg.h>
#include <stdio.h>
+#if defined(MR_WIN32)
+ #include <wchar.h>
+#endif
// On Windows, snprintf/vsnprintf may be synonyms for _snprintf/_vsnprintf and
// thus not conform to the C99 specification. Since it is next to impossible to
@@ -505,4 +508,12 @@ extern MR_bool MR_utf8_verify(const MR_String s);
extern MR_Integer MR_utf8_find_ill_formed_char(const MR_String s);
+// Accessing Unicode file names on Windows requires that we use the functions
+// taking wide character strings. The following functions handle the
+// conversions.
+#if defined(MR_WIN32)
+extern wchar_t *MR_utf8_to_wide(const char *s);
+extern char *MR_wide_to_utf8(const wchar_t *ws,
+#endif
+
#endif // not MERCURY_STRING_H
More information about the reviews
mailing list