11using System ;
22using System . Collections . Generic ;
3+ using System . Diagnostics ;
34using System . IO ;
45using System . Runtime . InteropServices ;
56using System . Security ;
67using System . Text ;
8+ using System . Text . RegularExpressions ;
79using System . Web ;
810using Microsoft . Build . Framework ;
911using Microsoft . Build . Utilities ;
@@ -18,18 +20,18 @@ public class CompileDatabase : Logger
1820{
1921 public override void Initialize ( IEventSource eventSource )
2022 {
21- string CompileOutputFilePath = "compile_commands.json" ;
22- string LinkOutputFilePath = "link_commands.json" ;
23+ string compileOutputFilePath = "compile_commands.json" ;
24+ string linkOutputFilePath = "link_commands.json" ;
2325
2426 try
2527 {
2628 const bool append = false ;
2729 Encoding utf8WithoutBom = new UTF8Encoding ( false ) ;
28- this . CompileStreamWriter = new StreamWriter ( CompileOutputFilePath , append , utf8WithoutBom ) ;
30+ this . CompileStreamWriter = new StreamWriter ( compileOutputFilePath , append , utf8WithoutBom ) ;
2931 this . firstLine = true ;
3032 CompileStreamWriter . WriteLine ( "[" ) ;
3133
32- this . LinkStreamWriter = new StreamWriter ( LinkOutputFilePath , append , utf8WithoutBom ) ;
34+ this . LinkStreamWriter = new StreamWriter ( linkOutputFilePath , append , utf8WithoutBom ) ;
3335 LinkStreamWriter . WriteLine ( "[" ) ;
3436 }
3537 catch ( Exception ex )
@@ -59,18 +61,55 @@ private void EventSource_AnyEventRaised(object sender, BuildEventArgs args)
5961 {
6062 if ( args is TaskCommandLineEventArgs taskArgs )
6163 {
62- const string clExe = ".exe " ;
63- int clExeIndex = taskArgs . CommandLine . IndexOf ( clExe ) ;
64- if ( clExeIndex == - 1 )
64+ string taskName = taskArgs . TaskName . ToLowerInvariant ( ) ;
65+ if ( taskName != "cl" && taskName != "link" && taskName != "lib" )
6566 {
66- throw new LoggerException ( "Unexpected lack of executable in " + taskArgs . CommandLine ) ;
67+ return ;
6768 }
6869
69- string exePath = taskArgs . CommandLine . Substring ( 0 , clExeIndex + clExe . Length - 1 ) ;
70- string argsString = taskArgs . CommandLine . Substring ( clExeIndex + clExe . Length ) . TrimStart ( ) ;
70+ int clExeIndex = 0 ;
71+ string exePath ;
72+ if ( taskArgs . CommandLine . Length > 0 && taskArgs . CommandLine [ 0 ] == '"' )
73+ {
74+ bool isEscaped = false ;
75+ clExeIndex ++ ;
76+ while ( clExeIndex < taskArgs . CommandLine . Length )
77+ {
78+ if ( isEscaped )
79+ {
80+ isEscaped = false ;
81+ }
82+ else if ( taskArgs . CommandLine [ clExeIndex ] == '"' )
83+ {
84+ break ;
85+ }
86+ else if ( taskArgs . CommandLine [ clExeIndex ] == '\\ ' )
87+ {
88+ isEscaped = true ;
89+ }
90+
91+ clExeIndex ++ ;
92+ }
93+
94+ clExeIndex ++ ;
95+ exePath = Regex . Unescape ( taskArgs . CommandLine . Substring ( 0 , clExeIndex ) ) ;
96+ }
97+ else
98+ {
99+ const string dotExe = ".exe" ;
100+ clExeIndex = taskArgs . CommandLine . IndexOf ( dotExe , StringComparison . OrdinalIgnoreCase ) + dotExe . Length ;
101+ if ( clExeIndex == - 1 )
102+ {
103+ Console . WriteLine ( "Unexpected lack of executable in " + taskArgs . CommandLine ) ;
104+ return ;
105+ }
106+
107+ exePath = taskArgs . CommandLine . Substring ( 0 , clExeIndex ) ;
108+ }
109+
110+ string argsString = taskArgs . CommandLine . Substring ( clExeIndex + 1 ) . TrimStart ( ) ;
71111 string [ ] cmdArgs = CommandLineToArgs ( argsString ) ;
72112 string dirname = Path . GetDirectoryName ( taskArgs . ProjectFile ) ;
73- String taskName = taskArgs . TaskName . ToLowerInvariant ( ) ;
74113
75114 if ( taskName == "cl" )
76115 {
@@ -93,7 +132,7 @@ private void EventSource_AnyEventRaised(object sender, BuildEventArgs args)
93132 ProcessCompileCommand ( exePath , cmdArgs , dirname ) ;
94133 }
95134 }
96- else if ( taskName == "link" || taskArgs . TaskName == "lib" )
135+ else if ( taskName == "link" || taskName == "lib" )
97136 {
98137 ProcessLinkCommand ( exePath , cmdArgs , dirname ) ;
99138 }
0 commit comments