1414import java .io .InputStream ;
1515import java .nio .charset .StandardCharsets ;
1616import java .util .ArrayList ;
17+ import java .util .Arrays ;
1718import java .util .Collection ;
1819import java .util .HashMap ;
1920import java .util .LinkedHashSet ;
2021import java .util .List ;
2122import java .util .Map ;
23+ import java .util .stream .Collectors ;
2224
2325import org .eclipse .cdt .core .CCorePlugin ;
2426import org .eclipse .cdt .core .envvar .IEnvironmentVariable ;
@@ -69,8 +71,9 @@ public final class CompilationDatabaseGenerator {
6971 /**
7072 * Checked on each build
7173 * Used before we look up the environment
74+ * Map of compiler name (as calculated by {@link #getCompilerName(String)}) to the absolute path of the compiler.
7275 */
73- private Map <ITool , String > toolMap = new HashMap <>();
76+ private Map <String , String > toolMap = new HashMap <>();
7477 private IProject project ;
7578 private IConfiguration configuration ;
7679 private ICSourceEntry [] srcEntries ;
@@ -229,18 +232,19 @@ private List<CompilationDatabaseInformation> populateObjList(IProject project, I
229232 outputLocation + "" , inputStrings , sourceLocation , outputLocation ); //$NON-NLS-1$
230233
231234 IBuildMacroProvider provider = ManagedBuildManager .getBuildMacroProvider ();
232- String compilerName = CompilationDatabaseGenerator .getCompilerName (tool );
233235 String commandLine = cmdLInfo .getCommandLine ();
234- commandLine = commandLine .replace (compilerName , "" ).trim (); //$NON-NLS-1$
235- String compilerPath = findCompilerInPath (tool , config );
236+ String compilerName = CompilationDatabaseGenerator .getCompilerName (commandLine );
237+ String compilerArguments = getCompilerArgs (commandLine );
238+ String compilerPath = findCompilerInPath (config , compilerName );
236239 String resolvedOptionFileContents ;
237240 if (compilerPath != null && !compilerPath .isEmpty ()) {
238- resolvedOptionFileContents = provider .resolveValueToMakefileFormat (compilerPath + " " + commandLine , //$NON-NLS-1$
241+ resolvedOptionFileContents = provider .resolveValueToMakefileFormat (
242+ compilerPath + " " + compilerArguments , //$NON-NLS-1$
239243 "" , " " , //$NON-NLS-1$//$NON-NLS-2$
240244 IBuildMacroProvider .CONTEXT_FILE ,
241245 new FileContextData (sourceLocation , outputLocation , null , tool ));
242246 } else {
243- resolvedOptionFileContents = provider .resolveValueToMakefileFormat (commandLine , "" , " " , //$NON-NLS-1$//$NON-NLS-2$
247+ resolvedOptionFileContents = provider .resolveValueToMakefileFormat (compilerArguments , "" , " " , //$NON-NLS-1$//$NON-NLS-2$
244248 IBuildMacroProvider .CONTEXT_FILE ,
245249 new FileContextData (sourceLocation , outputLocation , null , tool ));
246250
@@ -438,15 +442,15 @@ public boolean visit(IResourceProxy proxy) throws CoreException {
438442
439443 }
440444
441- private String findCompilerInPath (ITool tool , IConfiguration config ) {
442- if (toolMap .containsKey (tool )) {
443- return "\" " + toolMap .get (tool ) + "\" " ; //$NON-NLS-1$//$NON-NLS-2$
445+ private String findCompilerInPath (IConfiguration config , String compilerName ) {
446+ String cacheKey = compilerName ;
447+ if (toolMap .containsKey (cacheKey )) {
448+ return "\" " + toolMap .get (cacheKey ) + "\" " ; //$NON-NLS-1$//$NON-NLS-2$
444449 }
445- String compilerName = CompilationDatabaseGenerator .getCompilerName (tool );
446450 File pathToCompiler = new File (compilerName );
447451
448452 if (pathToCompiler .isAbsolute ()) {
449- toolMap .put (tool , compilerName );
453+ toolMap .put (cacheKey , compilerName );
450454 return "\" " + compilerName + "\" " ; //$NON-NLS-1$ //$NON-NLS-2$
451455 }
452456 ICConfigurationDescription cfg = ManagedBuildManager .getDescriptionForConfiguration (config );
@@ -458,7 +462,7 @@ private String findCompilerInPath(ITool tool, IConfiguration config) {
458462 IPath resolvedPath = PathUtil .findProgramLocation (compilerName , variable .getValue ());
459463 if (resolvedPath != null ) {
460464 String path = resolvedPath .toString ();
461- toolMap .put (tool , path );
465+ toolMap .put (cacheKey , path );
462466 return "\" " + path + "\" " ; //$NON-NLS-1$ //$NON-NLS-2$
463467 } else {
464468 return null ; // Only one PATH so can exit early
@@ -469,13 +473,32 @@ private String findCompilerInPath(ITool tool, IConfiguration config) {
469473 return null ;
470474 }
471475
472- private static String getCompilerName (ITool tool ) {
473- String compilerCommand = tool .getToolCommand ();
474- String [] arguments = CommandLineUtil .argumentsToArray (compilerCommand );
476+ private static String getCompilerName (String commandLine ) {
477+ String [] arguments = CommandLineUtil .argumentsToArray (commandLine );
475478 if (arguments .length == 0 ) {
476479 return "" ; //$NON-NLS-1$
477480 }
478481 return arguments [0 ];
479482 }
480483
484+ private static String getCompilerArgs (String commandLine ) {
485+ String [] arguments = CommandLineUtil .argumentsToArray (commandLine );
486+ if (arguments .length <= 1 ) {
487+ return "" ; //$NON-NLS-1$
488+ }
489+ List <String > argsList = Arrays .asList (arguments ).subList (1 , arguments .length );
490+ return escArgsForCompileCommand (argsList );
491+ }
492+
493+ private static String escArgsForCompileCommand (final List <String > args ) {
494+ return args .stream ().map (arg -> {
495+ if (arg .contains (" " ) || arg .contains ("\" " ) || arg .contains ("\\ " )) { //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
496+ String escaped = arg .replace ("\\ " , "\\ \\ " ).replace ("\" " , "\\ \" " ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$//$NON-NLS-4$
497+ return "\" " + escaped + "\" " ; //$NON-NLS-1$//$NON-NLS-2$
498+ } else {
499+ return arg ;
500+ }
501+ }).collect (Collectors .joining (" " )); //$NON-NLS-1$
502+ }
503+
481504}
0 commit comments