Skip to content

Commit d08de44

Browse files
committed
Internally use UTF-8 strings for Windows
Whenever interacting with external sources (eg. WinAPI functions) then encode/decode to/from Wide strings Fix Issue 14474
1 parent 7201eb7 commit d08de44

18 files changed

Lines changed: 452 additions & 117 deletions

src/backend/os.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,7 @@ int os_file_exists(const char *name)
651651
DWORD dw;
652652
int result;
653653

654-
dw = GetFileAttributes(name);
654+
dw = GetFileAttributesA(name);
655655
if (dw == -1L)
656656
result = 0;
657657
else if (dw & FILE_ATTRIBUTE_DIRECTORY)
@@ -710,7 +710,7 @@ char *file_8dot3name(const char *filename)
710710
char *buf;
711711
int i;
712712

713-
h = FindFirstFile(filename,&fileinfo);
713+
h = FindFirstFileA(filename,&fileinfo);
714714
if (h == INVALID_HANDLE_VALUE)
715715
return NULL;
716716
if (fileinfo.cAlternateFileName[0])
@@ -770,15 +770,15 @@ int file_write(char *name, void *buffer, unsigned len)
770770
HANDLE h;
771771
DWORD numwritten;
772772

773-
h = CreateFileA((LPTSTR)name,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,
773+
h = CreateFileA((LPCSTR)name,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,
774774
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,NULL);
775775
if (h == INVALID_HANDLE_VALUE)
776776
{
777777
if (GetLastError() == ERROR_PATH_NOT_FOUND)
778778
{
779779
if (!file_createdirs(name))
780780
{
781-
h = CreateFileA((LPTSTR)name,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,
781+
h = CreateFileA((LPCSTR)name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
782782
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,NULL);
783783
if (h != INVALID_HANDLE_VALUE)
784784
goto Lok;

src/dmd_msc.vcxproj

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,18 @@
2828
<ConfigurationType>Application</ConfigurationType>
2929
<WholeProgramOptimization Condition="'$(Configuration)'=='Release'">true</WholeProgramOptimization>
3030
</PropertyGroup>
31+
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
32+
<CharacterSet>Unicode</CharacterSet>
33+
</PropertyGroup>
34+
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
35+
<CharacterSet>Unicode</CharacterSet>
36+
</PropertyGroup>
37+
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
38+
<CharacterSet>Unicode</CharacterSet>
39+
</PropertyGroup>
40+
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
41+
<CharacterSet>Unicode</CharacterSet>
42+
</PropertyGroup>
3143
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
3244
<ImportGroup Label="ExtensionSettings">
3345
</ImportGroup>
@@ -43,7 +55,7 @@
4355
<ItemDefinitionGroup>
4456
<ClCompile>
4557
<AdditionalIncludeDirectories>.\root;.\tk;.\backend;.;vcbuild;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
46-
<PreprocessorDefinitions Condition="'$(Configuration)'=='Debug'">DEBUG;_DEBUG;TARGET_WINDOS%(PreprocessorDefinitions)</PreprocessorDefinitions>
58+
<PreprocessorDefinitions Condition="'$(Configuration)'=='Debug'">DEBUG;_DEBUG;TARGET_WINDOS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
4759
<PreprocessorDefinitions Condition="'$(Configuration)'=='Release'">TARGET_WINDOS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
4860
<RuntimeLibrary Condition="'$(Configuration)'=='Debug'">MultiThreadedDebug</RuntimeLibrary>
4961
<RuntimeLibrary Condition="'$(Configuration)'=='Release'">MultiThreaded</RuntimeLibrary>
@@ -237,6 +249,7 @@
237249
<ClCompile Include="root\outbuffer.c" />
238250
<ClCompile Include="root\speller.c" />
239251
<ClCompile Include="root\stringtable.c" />
252+
<ClCompile Include="root\utils.c" />
240253
<CustomBuild Include="idgen.d">
241254
<Message>Building and running $(IntDir)%(Filename).exe</Message>
242255
<Command>dmd -od$(IntDir) -of$(IntDir)%(Filename).exe %(Filename)%(Extension) &amp;&amp; $(IntDir)%(Filename).exe</Command>
@@ -363,6 +376,7 @@
363376
<ClInclude Include="root\root.h" />
364377
<ClInclude Include="root\speller.h" />
365378
<ClInclude Include="root\stringtable.h" />
379+
<ClInclude Include="root\utils.h" />
366380
<ClInclude Include="id.h" />
367381
<ClInclude Include="vcbuild\alloca.h" />
368382
<ClInclude Include="vcbuild\fenv.h" />

src/dmd_msc.vcxproj.filters

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -426,9 +426,6 @@
426426
<ClCompile Include="root\checkedint.c">
427427
<Filter>src\root</Filter>
428428
</ClCompile>
429-
<ClCompile Include="root\dmgcmem.c">
430-
<Filter>src\root</Filter>
431-
</ClCompile>
432429
<ClCompile Include="root\longdouble.c">
433430
<Filter>src\root</Filter>
434431
</ClCompile>
@@ -462,6 +459,9 @@
462459
<ClCompile Include="root\stringtable.c">
463460
<Filter>src\root</Filter>
464461
</ClCompile>
462+
<ClCompile Include="root\utils.c">
463+
<Filter>src\root</Filter>
464+
</ClCompile>
465465
<ClCompile Include="cdxxx.c">
466466
<Filter>src\generated</Filter>
467467
</ClCompile>
@@ -758,6 +758,9 @@
758758
<ClInclude Include="root\stringtable.h">
759759
<Filter>src\root</Filter>
760760
</ClInclude>
761+
<ClInclude Include="root\utils.h">
762+
<Filter>src\root</Filter>
763+
</ClInclude>
761764
<ClInclude Include="id.h">
762765
<Filter>src\generated</Filter>
763766
</ClInclude>
@@ -779,9 +782,6 @@
779782
<ClInclude Include="nspace.h">
780783
<Filter>src</Filter>
781784
</ClInclude>
782-
<ClInclude Include="backend\obj.h">
783-
<Filter>src\backend</Filter>
784-
</ClInclude>
785785
<ClInclude Include="tokens.h">
786786
<Filter>src</Filter>
787787
</ClInclude>
@@ -790,9 +790,6 @@
790790
</ClInclude>
791791
</ItemGroup>
792792
<ItemGroup>
793-
<CustomBuild Include="idgen.c">
794-
<Filter>src\gen</Filter>
795-
</CustomBuild>
796793
<CustomBuild Include="impcnvgen.c">
797794
<Filter>src\gen</Filter>
798795
</CustomBuild>
@@ -803,5 +800,6 @@
803800
<CustomBuild Include="vcbuild\ldfpu.asm">
804801
<Filter>src\vcbuild</Filter>
805802
</CustomBuild>
803+
<CustomBuild Include="idgen.d" />
806804
</ItemGroup>
807805
</Project>

src/errors.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "errors.h"
2626
#include "outbuffer.h"
2727
#include "rmem.h"
28+
#include "utils.h"
2829

2930
enum COLOR
3031
{
@@ -176,8 +177,15 @@ void verrorPrint(Loc loc, COLOR headerColor, const char *header, const char *for
176177

177178
if (global.params.color)
178179
setConsoleColorBright(true);
179-
if (*p)
180+
if (*p) {
181+
#ifdef _WIN32
182+
LPCWSTR wstr = UTF8toWide(p);
183+
fwprintf(stderr, L"%s\n", wstr);
184+
free((void *)wstr);
185+
#else
180186
fprintf(stderr, "%s: ", p);
187+
#endif
188+
}
181189
mem.xfree(p);
182190

183191
if (global.params.color)
@@ -191,7 +199,13 @@ void verrorPrint(Loc loc, COLOR headerColor, const char *header, const char *for
191199
fprintf(stderr, "%s ", p2);
192200
OutBuffer tmp;
193201
tmp.vprintf(format, ap);
202+
#ifdef _WIN32
203+
LPCWSTR wstr = UTF8toWide(tmp.peekString());
204+
fwprintf(stderr, L"%s\n", wstr);
205+
free((void *)wstr);
206+
#else
194207
fprintf(stderr, "%s\n", tmp.peekString());
208+
#endif
195209
fflush(stderr);
196210
}
197211

src/inifile.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "root.h"
3232
#include "rmem.h"
3333
#include "port.h"
34+
#include "utils.h"
3435

3536
#define LOG 0
3637

@@ -63,15 +64,17 @@ const char *findConfFile(const char *argv0, const char *inifile)
6364
* o directory off of argv0
6465
* o SYSCONFDIR (default=/etc/) (non-windows)
6566
*/
66-
const char *filename = FileName::combine(getenv("HOME"), inifile);
67+
const char *filename = FileName::combine(dgetenv("HOME"), inifile);
6768
if (FileName::exists(filename))
6869
return filename;
6970

7071
#if _WIN32 // This fix by Tim Matthews
71-
char resolved_name[MAX_PATH + 1];
72-
if (GetModuleFileNameA(NULL, resolved_name, MAX_PATH + 1) && FileName::exists(resolved_name))
72+
WCHAR wresolved_name[MAX_PATH + 1];
73+
if (GetModuleFileNameW(NULL, wresolved_name, MAX_PATH + 1) && FileName::exists(wresolved_name))
7374
{
75+
char *resolved_name = wideToUTF8(wresolved_name);
7476
filename = FileName::replaceName(resolved_name, inifile);
77+
free(resolved_name);
7578
if (FileName::exists(filename))
7679
return filename;
7780
}
@@ -204,7 +207,7 @@ void parseConfFile(const char *filename, const char *envsectionname)
204207
memcpy(p, &line[k + 1], len2);
205208
p[len2] = 0;
206209
Port::strupr(p);
207-
char *penv = getenv(p);
210+
char *penv = dgetenv(p);
208211
if (penv)
209212
buf.writestring(penv);
210213
free(p);
@@ -267,7 +270,7 @@ void parseConfFile(const char *filename, const char *envsectionname)
267270
else if (p[0] == '?' && p[1] == '=')
268271
{
269272
*p = '\0';
270-
if (getenv(pn))
273+
if (dgetenv(pn))
271274
{
272275
pn = NULL;
273276
break;
@@ -289,7 +292,7 @@ void parseConfFile(const char *filename, const char *envsectionname)
289292

290293
if (pn)
291294
{
292-
putenv(strdup(pn));
295+
dputenv(strdup(pn));
293296
#if LOG
294297
printf("\tputenv('%s')\n", pn);
295298
//printf("getenv(\"TEST\") = '%s'\n",getenv("TEST"));

src/link.c

Lines changed: 10 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,13 @@
1616
#include <string.h>
1717
#include <stdlib.h>
1818

19-
#if _WIN32
20-
#include <process.h>
21-
#ifdef _MSC_VER
22-
#include <windows.h>
23-
#endif
24-
#endif
25-
2619
#if __linux__ || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun
2720
#include <sys/types.h>
2821
#include <sys/wait.h>
2922
#include <unistd.h>
3023
#endif
3124

32-
#if __linux__ || __APPLE__
33-
#define HAS_POSIX_SPAWN 1
34-
#include <spawn.h>
35-
#if __APPLE__
36-
#include <crt_externs.h>
37-
#endif
38-
#else
39-
#define HAS_POSIX_SPAWN 0
40-
#endif
25+
#include "utils.h"
4126

4227
#include "root.h"
4328

@@ -248,7 +233,7 @@ int runLINK()
248233

249234
/* Append the path to the VC lib files, and then the SDK lib files
250235
*/
251-
const char *vcinstalldir = getenv("VCINSTALLDIR");
236+
const char *vcinstalldir = dgetenv("VCINSTALLDIR");
252237
if (vcinstalldir)
253238
{ cmdbuf.writestring(" /LIBPATH:\"");
254239
cmdbuf.writestring(vcinstalldir);
@@ -258,7 +243,7 @@ int runLINK()
258243
cmdbuf.writestring("\\lib\"");
259244
}
260245

261-
const char *windowssdkdir = getenv("WindowsSdkDir");
246+
const char *windowssdkdir = dgetenv("WindowsSdkDir");
262247
if (windowssdkdir)
263248
{ cmdbuf.writestring(" /LIBPATH:\"");
264249
cmdbuf.writestring(windowssdkdir);
@@ -284,9 +269,9 @@ int runLINK()
284269
sprintf(p, "@%s", lnkfilename);
285270
}
286271

287-
const char *linkcmd = getenv(global.params.is64bit ? "LINKCMD64" : "LINKCMD");
272+
const char *linkcmd = dgetenv(global.params.is64bit ? "LINKCMD64" : "LINKCMD");
288273
if (!linkcmd)
289-
linkcmd = getenv("LINKCMD"); // backward compatible
274+
linkcmd = dgetenv("LINKCMD"); // backward compatible
290275
if (!linkcmd)
291276
{
292277
if (vcinstalldir)
@@ -435,7 +420,7 @@ int runLINK()
435420
sprintf(p, "@%s", lnkfilename);
436421
}
437422

438-
const char *linkcmd = getenv("LINKCMD");
423+
const char *linkcmd = dgetenv("LINKCMD");
439424
if (!linkcmd)
440425
linkcmd = "link";
441426
int status = executecmd(linkcmd, p);
@@ -747,7 +732,6 @@ int executecmd(const char *cmd, const char *args)
747732
{
748733
int status;
749734
size_t len;
750-
751735
if (global.params.verbose)
752736
fprintf(global.stdmsg, "%s %s\n", cmd, args);
753737

@@ -757,7 +741,7 @@ int executecmd(const char *cmd, const char *args)
757741
{
758742
char *q = (char *) alloca(8 + len + 1);
759743
sprintf(q,"_CMDLINE=%s", args);
760-
status = putenv(q);
744+
status = dputenv(q);
761745
if (status == 0)
762746
{
763747
args = "@_CMDLINE";
@@ -772,23 +756,10 @@ int executecmd(const char *cmd, const char *args)
772756
// Normalize executable path separators, see Bugzilla 9330
773757
cmd = toWinPath(cmd);
774758

775-
#ifdef _MSC_VER
776-
if(strchr(cmd, ' '))
777-
{
778-
// MSVCRT: spawn does not work with spaces in the executable
779-
size_t cmdlen = strlen(cmd);
780-
char* shortName = new char[cmdlen + 1]; // enough space
781-
DWORD len = GetShortPathName(cmd, shortName, cmdlen + 1);
782-
if(len > 0 && len <= cmdlen)
783-
cmd = shortName;
784-
}
785-
#endif
786-
787759
status = executearg0(cmd,args);
788760
if (status == -1)
789761
{
790-
// spawnlp returns intptr_t in some systems, not int
791-
status = spawnlp(0,cmd,cmd,args,NULL);
762+
status = dspawnlp(0,cmd,cmd,args,NULL);
792763
}
793764

794765
// if (global.params.verbose)
@@ -827,8 +798,7 @@ int executearg0(const char *cmd, const char *args)
827798
file = FileName::replaceName(argv0, cmd);
828799

829800
//printf("spawning '%s'\n",file);
830-
// spawnlp returns intptr_t in some systems, not int
831-
return spawnl(0,file,file,args,NULL);
801+
return dspawnl(0,file,file,args,NULL);
832802
}
833803
#endif
834804

@@ -854,15 +824,6 @@ int runProgram()
854824
argv.push(global.params.exefile);
855825
for (size_t i = 0; i < global.params.runargs_length; i++)
856826
{ const char *a = global.params.runargs[i];
857-
858-
#if _WIN32
859-
// BUG: what about " appearing in the string?
860-
if (strchr(a, ' '))
861-
{ char *b = (char *)mem.xmalloc(3 + strlen(a));
862-
sprintf(b, "\"%s\"", a);
863-
a = b;
864-
}
865-
#endif
866827
argv.push(a);
867828
}
868829
argv.push(NULL);
@@ -873,8 +834,7 @@ int runProgram()
873834
ex = FileName::combine(".", ex);
874835
else
875836
ex = global.params.exefile;
876-
// spawnlp returns intptr_t in some systems, not int
877-
return spawnv(0,ex,argv.tdata());
837+
return dspawnv(0,ex,argv.tdata());
878838
#elif __linux__ || __APPLE__ || __FreeBSD__ || __OpenBSD__ || __sun
879839
pid_t childpid;
880840
int status;

0 commit comments

Comments
 (0)