@@ -56,16 +56,22 @@ int main(string[] argv)
5656 int skipargs = 0 ;
5757 string depsfile;
5858 bool doDemangle = true ;
59+ bool demangleAll = false ; // not just linker messages
5960 bool gdcMode = false ; // gcc linker
60- bool msMode = false ; // microsft linker
61+ bool msMode = false ; // microsoft linker
6162 bool verbose = false ;
6263
6364 while (argv.length >= skipargs + 2 )
6465 {
6566 if (argv[skipargs + 1 ] == " -nodemangle" )
6667 {
6768 doDemangle = false ;
68- skipargs = 1 ;
69+ skipargs++ ;
70+ }
71+ else if (argv[skipargs + 1 ] == " -demangleall" )
72+ {
73+ demangleAll = true ;
74+ skipargs++ ;
6975 }
7076 else if (argv[skipargs + 1 ] == " -gdcmode" )
7177 {
@@ -136,7 +142,7 @@ int main(string[] argv)
136142 if (verbose)
137143 printf(" Command: %.*s\n " , command.length, command.ptr);
138144
139- int exitCode = runProcess(command, inject ? depsfile : null , doDemangle, gdcMode, msMode);
145+ int exitCode = runProcess(command, inject ? depsfile : null , doDemangle, demangleAll, gdcMode, msMode);
140146
141147 if (exitCode == 0 && trackfile.length > 0 )
142148 {
@@ -157,7 +163,7 @@ int main(string[] argv)
157163 return exitCode;
158164}
159165
160- int runProcess (string command, string depsfile, bool doDemangle, bool gdcMode, bool msMode)
166+ int runProcess (string command, string depsfile, bool doDemangle, bool demangleAll, bool gdcMode, bool msMode)
161167{
162168 HANDLE hStdOutRead;
163169 HANDLE hStdOutWrite;
@@ -230,12 +236,10 @@ int runProcess(string command, string depsfile, bool doDemangle, bool gdcMode, b
230236 ResumeThread(piProcInfo.hThread);
231237
232238 char [] buffer = new char [2048 ];
233- WCHAR [] decodeBufferWide;
234- char [] decodeBuffer;
235239 DWORD bytesRead = 0 ;
236240 DWORD bytesAvaiable = 0 ;
237241 DWORD exitCode = 0 ;
238- bool linkerFound = gdcMode || msMode;
242+ bool linkerFound = gdcMode || msMode || demangleAll ;
239243
240244 while (true )
241245 {
@@ -255,59 +259,7 @@ int runProcess(string command, string depsfile, bool doDemangle, bool gdcMode, b
255259 if (! bSuccess || bytesRead == 0 )
256260 break ;
257261
258- bytesRead-- ; // remove \n
259- while (bytesRead > 0 && buffer[bytesRead- 1 ] == ' \r ' ) // remove \r
260- bytesRead-- ;
261- DWORD skip = 0 ;
262- while (skip < bytesRead && buffer[skip] == ' \r ' ) // remove \r
263- skip++ ;
264-
265- char [] output = buffer[skip.. bytesRead];
266- if (msMode) // the microsoft linker outputs the error messages in the default ANSI codepage so we need to convert it to UTF-8
267- {
268- if (decodeBufferWide.length < output.length + 1 )
269- {
270- decodeBufferWide.length = output.length + 1 ;
271- decodeBuffer.length = 2 * output.length + 1 ;
272- }
273- auto numDecoded = MultiByteToWideChar(CP_ACP , 0 , output.ptr, output.length, decodeBufferWide.ptr, decodeBufferWide.length);
274- auto numEncoded = WideCharToMultiByte(CP_UTF8 , 0 , decodeBufferWide.ptr, numDecoded, decodeBuffer.ptr, decodeBuffer.length, null , null );
275- output = decodeBuffer[0 .. numEncoded];
276- }
277- size_t writepos = 0 ;
278-
279- if (! linkerFound)
280- {
281- if (output.startsWith(" OPTLINK (R)" ))
282- linkerFound = true ;
283- else if (output.countUntil(" error LNK" ) >= 0 || output.countUntil(" warning LNK" ) >= 0 )
284- linkerFound = msMode = true ;
285- }
286-
287- if (doDemangle && linkerFound)
288- {
289- if (gdcMode)
290- {
291- if (output.countUntil(" undefined reference to" ) >= 0 || output.countUntil(" In function" ) >= 0 )
292- {
293- processLine(output, writepos, false , cp);
294- }
295- }
296- else if (msMode)
297- {
298- if (output.countUntil(" LNK" ) >= 0 )
299- {
300- processLine(output, writepos, false , cp);
301- }
302- }
303- else
304- {
305- processLine(output, writepos, true , cp);
306- }
307- }
308- if (writepos < output.length)
309- fwrite(output.ptr + writepos, output.length - writepos, 1 , stdout);
310- fputc(' \n ' , stdout);
262+ demangleLine(buffer[0 .. bytesRead], doDemangle, demangleAll, msMode, gdcMode, cp, linkerFound);
311263 }
312264 else
313265 {
@@ -327,6 +279,66 @@ int runProcess(string command, string depsfile, bool doDemangle, bool gdcMode, b
327279 return exitCode;
328280}
329281
282+ void demangleLine (char [] output, bool doDemangle, bool demangleAll, bool msMode, bool gdcMode, int cp, ref bool linkerFound)
283+ {
284+ if (output.length && output[$- 1 ] == ' \n ' ) // remove trailing \n
285+ output = output[0 .. $- 1 ];
286+ while (output.length && output[$- 1 ] == ' \r ' ) // remove trailing \r
287+ output = output[0 .. $- 1 ];
288+
289+ while (output.length && output[0 ] == ' \r ' ) // remove preceding \r
290+ output = output[1 .. $];
291+
292+ if (msMode) // the microsoft linker outputs the error messages in the default ANSI codepage so we need to convert it to UTF-8
293+ {
294+ static WCHAR [] decodeBufferWide;
295+ static char [] decodeBuffer;
296+
297+ if (decodeBufferWide.length < output.length + 1 )
298+ {
299+ decodeBufferWide.length = output.length + 1 ;
300+ decodeBuffer.length = 2 * output.length + 1 ;
301+ }
302+ auto numDecoded = MultiByteToWideChar(CP_ACP , 0 , output.ptr, output.length, decodeBufferWide.ptr, decodeBufferWide.length);
303+ auto numEncoded = WideCharToMultiByte(CP_UTF8 , 0 , decodeBufferWide.ptr, numDecoded, decodeBuffer.ptr, decodeBuffer.length, null , null );
304+ output = decodeBuffer[0 .. numEncoded];
305+ }
306+ size_t writepos = 0 ;
307+
308+ if (! linkerFound)
309+ {
310+ if (output.startsWith(" OPTLINK (R)" ))
311+ linkerFound = true ;
312+ else if (output.countUntil(" error LNK" ) >= 0 || output.countUntil(" warning LNK" ) >= 0 )
313+ linkerFound = msMode = true ;
314+ }
315+
316+ if (doDemangle && linkerFound)
317+ {
318+ if (gdcMode)
319+ {
320+ if (demangleAll || output.countUntil(" undefined reference to" ) >= 0 || output.countUntil(" In function" ) >= 0 )
321+ {
322+ processLine(output, writepos, false , cp);
323+ }
324+ }
325+ else if (msMode)
326+ {
327+ if (demangleAll || output.countUntil(" LNK" ) >= 0 )
328+ {
329+ processLine(output, writepos, false , cp);
330+ }
331+ }
332+ else
333+ {
334+ processLine(output, writepos, true , cp);
335+ }
336+ }
337+ if (writepos < output.length)
338+ fwrite(output.ptr + writepos, output.length - writepos, 1 , stdout);
339+ fputc(' \n ' , stdout);
340+ }
341+
330342void processLine (char [] output, ref size_t writepos, bool optlink, int cp)
331343{
332344 for (int p = 0 ; p < output.length; p++ )
0 commit comments