shithub: choc

Download patch

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)
     {