1
1
using System ;
2
2
using System . Collections . Generic ;
3
+ using System . Diagnostics ;
3
4
using System . IO ;
4
5
using System . Runtime . InteropServices ;
5
6
using System . Security ;
6
7
using System . Text ;
8
+ using System . Text . RegularExpressions ;
7
9
using System . Web ;
8
10
using Microsoft . Build . Framework ;
9
11
using Microsoft . Build . Utilities ;
@@ -18,18 +20,18 @@ public class CompileDatabase : Logger
18
20
{
19
21
public override void Initialize ( IEventSource eventSource )
20
22
{
21
- string CompileOutputFilePath = "compile_commands.json" ;
22
- string LinkOutputFilePath = "link_commands.json" ;
23
+ string compileOutputFilePath = "compile_commands.json" ;
24
+ string linkOutputFilePath = "link_commands.json" ;
23
25
24
26
try
25
27
{
26
28
const bool append = false ;
27
29
Encoding utf8WithoutBom = new UTF8Encoding ( false ) ;
28
- this . CompileStreamWriter = new StreamWriter ( CompileOutputFilePath , append , utf8WithoutBom ) ;
30
+ this . CompileStreamWriter = new StreamWriter ( compileOutputFilePath , append , utf8WithoutBom ) ;
29
31
this . firstLine = true ;
30
32
CompileStreamWriter . WriteLine ( "[" ) ;
31
33
32
- this . LinkStreamWriter = new StreamWriter ( LinkOutputFilePath , append , utf8WithoutBom ) ;
34
+ this . LinkStreamWriter = new StreamWriter ( linkOutputFilePath , append , utf8WithoutBom ) ;
33
35
LinkStreamWriter . WriteLine ( "[" ) ;
34
36
}
35
37
catch ( Exception ex )
@@ -59,18 +61,55 @@ private void EventSource_AnyEventRaised(object sender, BuildEventArgs args)
59
61
{
60
62
if ( args is TaskCommandLineEventArgs taskArgs )
61
63
{
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" )
65
66
{
66
- throw new LoggerException ( "Unexpected lack of executable in " + taskArgs . CommandLine ) ;
67
+ return ;
67
68
}
68
69
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 ( ) ;
71
111
string [ ] cmdArgs = CommandLineToArgs ( argsString ) ;
72
112
string dirname = Path . GetDirectoryName ( taskArgs . ProjectFile ) ;
73
- String taskName = taskArgs . TaskName . ToLowerInvariant ( ) ;
74
113
75
114
if ( taskName == "cl" )
76
115
{
@@ -93,7 +132,7 @@ private void EventSource_AnyEventRaised(object sender, BuildEventArgs args)
93
132
ProcessCompileCommand ( exePath , cmdArgs , dirname ) ;
94
133
}
95
134
}
96
- else if ( taskName == "link" || taskArgs . TaskName == "lib" )
135
+ else if ( taskName == "link" || taskName == "lib" )
97
136
{
98
137
ProcessLinkCommand ( exePath , cmdArgs , dirname ) ;
99
138
}
0 commit comments