commit 8c723c09234bbfdda47b12e65ca8dfbd58e18673
Author: Roman Fomin <rfomin@gmail.com>
AuthorDate: Mon Aug 15 13:15:58 2022 +0700
Commit: GitHub <noreply@github.com>
CommitDate: Mon Aug 15 08:15:58 2022 +0200
Implement M_getenv() wrapper to support non-Latin paths on Windows (#1486)
* implement M_getenv wrapper for non-Latin paths support on Windows
* update HACKING.md
---
HACKING.md | 1 +
src/d_iwad.c | 4 ++--
src/m_misc.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++----
src/m_misc.h | 3 ++-
src/setup/execute.c | 2 +-
5 files changed, 66 insertions(+), 8 deletions(-)
diff --git a/HACKING.md b/HACKING.md
index 57818478..792136e8 100644
--- a/HACKING.md
+++ b/HACKING.md
@@ -227,6 +227,7 @@ C library function | Wrapper
`rename()` | `M_rename()`
`stat()` | `M_stat()`
`mkdir()` | `M_MakeDirectory()`
+`getenv()` | `M_getenv()`
## GNU GPL and licensing
diff --git a/src/d_iwad.c b/src/d_iwad.c
index 6b4380a4..e6e5ffe3 100644
--- a/src/d_iwad.c
+++ b/src/d_iwad.c
@@ -744,14 +744,14 @@ static void BuildIWADDirList(void)
AddIWADDir(M_DirName(myargv[0]));
// Add DOOMWADDIR if it is in the environment
- env = getenv("DOOMWADDIR");
+ env = M_getenv("DOOMWADDIR");
if (env != NULL)
{
AddIWADDir(env);
}
// Add dirs from DOOMWADPATH:
- env = getenv("DOOMWADPATH");
+ env = M_getenv("DOOMWADPATH");
if (env != NULL)
{
AddIWADPath(env, "");
diff --git a/src/m_misc.c b/src/m_misc.c
index 5b8f22b3..9ede5581 100644
--- a/src/m_misc.c
+++ b/src/m_misc.c
@@ -28,6 +28,7 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <io.h>
+#include "SDL_stdinc.h" // SDL_iconv_string
#ifdef _MSC_VER
#include <direct.h>
#endif
@@ -58,7 +59,7 @@ wchar_t *M_ConvertUtf8ToWide(const char *str)
if (!wlen)
{
errno = EINVAL;
- printf("Warning: Failed to convert path to UTF8\n");
+ printf("M_ConvertUtf8ToWide: Failed to convert path from UTF8\n");
return NULL;
}
@@ -73,7 +74,7 @@ wchar_t *M_ConvertUtf8ToWide(const char *str)
if (MultiByteToWideChar(CP_UTF8, 0, str, -1, wstr, wlen) == 0)
{
errno = EINVAL;
- printf("Warning: Failed to convert path to UTF8\n");
+ printf("M_ConvertUtf8ToWide: Failed to convert path from UTF8\n");
free(wstr);
return NULL;
}
@@ -82,7 +83,7 @@ wchar_t *M_ConvertUtf8ToWide(const char *str)
}
#endif
-FILE* M_fopen(const char *filename, const char *mode)
+FILE *M_fopen(const char *filename, const char *mode)
{
#ifdef _WIN32
FILE *file;
@@ -200,6 +201,61 @@ int M_stat(const char *path, struct stat *buf)
#endif
}
+#ifdef _WIN32
+typedef struct {
+ char *var;
+ const char *name;
+} env_var_t;
+
+static env_var_t *env_vars;
+static int num_vars;
+#endif
+
+char *M_getenv(const char *name)
+{
+#ifdef _WIN32
+ int i;
+ wchar_t *wenv = NULL, *wname = NULL;
+ char *env = NULL;
+
+ for (i = 0; i < num_vars; ++i)
+ {
+ if (!strcasecmp(name, env_vars[i].name))
+ return env_vars[i].var;
+ }
+
+ wname = M_ConvertUtf8ToWide(name);
+
+ if (!wname)
+ {
+ return NULL;
+ }
+
+ wenv = _wgetenv(wname);
+
+ free(wname);
+
+ if (wenv)
+ {
+ env = SDL_iconv_string("UTF-8", "UTF-16LE", (const char *)wenv,
+ (wcslen(wenv) + 1) * sizeof(wchar_t));
+ }
+ else
+ {
+ env = NULL;
+ }
+
+ env_vars = I_Realloc(env_vars, (num_vars + 1) * sizeof(*env_vars));
+ env_vars[num_vars].var = env;
+ env_vars[num_vars].name = M_StringDuplicate(name);
+ ++num_vars;
+
+ return env;
+#else
+ return getenv(name);
+#endif
+}
+
//
// Create a directory
//
@@ -405,7 +461,7 @@ char *M_TempFile(const char *s)
// Check the TEMP environment variable to find the location.
- tempdir = getenv("TEMP");
+ tempdir = M_getenv("TEMP");
if (tempdir == NULL)
{
diff --git a/src/m_misc.h b/src/m_misc.h
index f9a6beff..c04e050e 100644
--- a/src/m_misc.h
+++ b/src/m_misc.h
@@ -30,10 +30,11 @@
wchar_t *M_ConvertUtf8ToWide(const char *str);
#endif
-FILE* M_fopen(const char *filename, const char *mode);
+FILE *M_fopen(const char *filename, const char *mode);
int M_remove(const char *path);
int M_rename(const char *oldname, const char *newname);
int M_stat(const char *path, struct stat *buf);
+char *M_getenv(const char *name);
boolean M_WriteFile(const char *name, const void *source, int length);
int M_ReadFile(const char *name, byte **buffer);
void M_MakeDirectory(const char *dir);
diff --git a/src/setup/execute.c b/src/setup/execute.c
index e297f40e..0a86dd7b 100644
--- a/src/setup/execute.c
+++ b/src/setup/execute.c
@@ -61,7 +61,7 @@ static char *TempFile(const char *s)
#ifdef _WIN32
// Check the TEMP environment variable to find the location.
- tempdir = getenv("TEMP");
+ tempdir = M_getenv("TEMP");
if (tempdir == NULL)
{