ref: 8c723c09234bbfdda47b12e65ca8dfbd58e18673
parent: e49be7669f9072e2e27e67e29c097591a83bbf06
author: Roman Fomin <[email protected]>
date: Mon Aug 15 09:15:58 EDT 2022
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
--- a/HACKING.md
+++ b/HACKING.md
@@ -227,6 +227,7 @@
`rename()` | `M_rename()`
`stat()` | `M_stat()`
`mkdir()` | `M_MakeDirectory()`
+`getenv()` | `M_getenv()`
## GNU GPL and licensing
--- a/src/d_iwad.c
+++ b/src/d_iwad.c
@@ -744,7 +744,7 @@
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);
@@ -751,7 +751,7 @@
}
// Add dirs from DOOMWADPATH:
- env = getenv("DOOMWADPATH");
+ env = M_getenv("DOOMWADPATH");
if (env != NULL)
{
AddIWADPath(env, "");
--- 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 @@
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 @@
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 @@
}
#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 @@
#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 @@
// Check the TEMP environment variable to find the location.
- tempdir = getenv("TEMP");
+ tempdir = M_getenv("TEMP");
if (tempdir == NULL)
{
--- 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);
--- a/src/setup/execute.c
+++ b/src/setup/execute.c
@@ -61,7 +61,7 @@
#ifdef _WIN32
// Check the TEMP environment variable to find the location.
- tempdir = getenv("TEMP");
+ tempdir = M_getenv("TEMP");
if (tempdir == NULL)
{