Skip to content

Commit 0e53389

Browse files
authored
Add a directory tracker to the CBS Makefile builder (#1071)
Messages such as "make: Entering directory" are now processed so that the scanner info builder knows the correct full path to use for build. Without this code calls to ToolChain.getResourcesFromCommand() would pass in the wrong directory and resources could not be reliably calculated. With the incorrect calculation the scanner info does not get applied to the file correctly and the file cannot be indexed reliably.
1 parent 3fc221a commit 0e53389

File tree

1 file changed

+83
-0
lines changed

1 file changed

+83
-0
lines changed

core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/build/StandardBuildConfiguration.java

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,16 @@
1111
package org.eclipse.cdt.core.build;
1212

1313
import java.io.IOException;
14+
import java.net.URI;
1415
import java.nio.file.Path;
1516
import java.nio.file.Paths;
1617
import java.util.ArrayList;
1718
import java.util.Arrays;
1819
import java.util.List;
1920
import java.util.Map;
21+
import java.util.Stack;
22+
import java.util.regex.Matcher;
23+
import java.util.regex.Pattern;
2024

2125
import org.eclipse.cdt.core.CCorePlugin;
2226
import org.eclipse.cdt.core.ConsoleOutputStream;
@@ -70,6 +74,7 @@ public class StandardBuildConfiguration extends CBuildConfiguration {
7074
private String cleanCommand = DEFAULT_CLEAN_COMMAND;
7175
private IContainer buildContainer;
7276
private IEnvironmentVariable[] envVars;
77+
private Stack<String> directoryStack = new Stack<>();
7378

7479
public StandardBuildConfiguration(IBuildConfiguration config, String name) throws CoreException {
7580
super(config, name);
@@ -361,4 +366,82 @@ public void clean(IConsole console, IProgressMonitor monitor) throws CoreExcepti
361366
}
362367
}
363368

369+
private abstract class DirectoryPatternParser {
370+
private final Pattern pattern;
371+
372+
public DirectoryPatternParser(String regex) {
373+
this.pattern = Pattern.compile(regex);
374+
}
375+
376+
public void processLine(String line) {
377+
Matcher matcher = pattern.matcher(line);
378+
if (matcher.find()) {
379+
recordDirectoryChange(matcher);
380+
}
381+
}
382+
383+
abstract protected void recordDirectoryChange(Matcher matcher);
384+
}
385+
386+
private final List<DirectoryPatternParser> enteringDirectoryPatterns = List.of( //
387+
//
388+
new DirectoryPatternParser("make\\[(.*)\\]: Entering directory [`'](.*)'") { //$NON-NLS-1$
389+
@Override
390+
protected void recordDirectoryChange(Matcher matcher) {
391+
int level;
392+
try {
393+
level = Integer.valueOf(matcher.group(1)).intValue();
394+
} catch (NumberFormatException e) {
395+
level = 0;
396+
}
397+
String dir = matcher.group(2);
398+
/*
399+
* Sometimes make screws up the output, so "leave" events can't be seen. Double-check
400+
* level here.
401+
*/
402+
int parseLevel = directoryStack.size();
403+
for (; level < parseLevel; level++) {
404+
if (!directoryStack.empty()) {
405+
directoryStack.pop();
406+
}
407+
}
408+
directoryStack.push(dir);
409+
}
410+
},
411+
412+
// This is emitted by GNU make using options -w or --print-directory.
413+
new DirectoryPatternParser("make: Entering directory [`'](.*)'") { //$NON-NLS-1$
414+
@Override
415+
protected void recordDirectoryChange(Matcher matcher) {
416+
String dir = matcher.group(1);
417+
directoryStack.push(dir);
418+
}
419+
},
420+
421+
//
422+
new DirectoryPatternParser("make(\\[.*\\])?: Leaving directory") { //$NON-NLS-1$
423+
@Override
424+
protected void recordDirectoryChange(Matcher matcher) {
425+
if (!directoryStack.empty()) {
426+
directoryStack.pop();
427+
}
428+
}
429+
}
430+
431+
);
432+
433+
@Override
434+
public boolean processLine(String line) {
435+
enteringDirectoryPatterns.forEach(p -> p.processLine(line));
436+
return super.processLine(line);
437+
}
438+
439+
@Override
440+
public URI getBuildDirectoryURI() throws CoreException {
441+
if (!directoryStack.isEmpty()) {
442+
return Path.of(directoryStack.peek()).toUri();
443+
} else {
444+
return super.getBuildDirectoryURI();
445+
}
446+
}
364447
}

0 commit comments

Comments
 (0)