mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-23 17:05:26 +02:00
Bug 45203. Improved loop detection.
This commit is contained in:
parent
a4ebf6ffa5
commit
163df7dbad
2 changed files with 24 additions and 19 deletions
|
@ -32,9 +32,9 @@ public class IncludeMapTest extends TestCase {
|
|||
});
|
||||
map.transitivelyClose();
|
||||
IncludeMap expected = new IncludeMap(false, false, new String[] {
|
||||
"a", "c",
|
||||
"a", "b",
|
||||
"a", "d",
|
||||
"a", "c",
|
||||
"b", "d",
|
||||
"b", "c",
|
||||
"c", "d",
|
||||
|
@ -54,7 +54,7 @@ public class IncludeMapTest extends TestCase {
|
|||
});
|
||||
map.transitivelyClose();
|
||||
IncludeMap expected = new IncludeMap(true, false, new String[] {
|
||||
"a", "c",
|
||||
"a", "b",
|
||||
"c", "b",
|
||||
"d", "b",
|
||||
});
|
||||
|
|
|
@ -25,6 +25,9 @@ import org.eclipse.ui.IMemento;
|
|||
import org.eclipse.ui.WorkbenchException;
|
||||
import org.eclipse.ui.XMLMemento;
|
||||
|
||||
/**
|
||||
* A set of header file substitution rules.
|
||||
*/
|
||||
public class IncludeMap {
|
||||
private static final String TAG_CPP_ONLY = "cpp_only"; //$NON-NLS-1$
|
||||
private static final String TAG_FORCED_REPLACEMENT = "forced_replacement"; //$NON-NLS-1$
|
||||
|
@ -195,21 +198,23 @@ public class IncludeMap {
|
|||
List<IncludeInfo> targets = entry.getValue();
|
||||
ArrayDeque<IncludeInfo> queue = new ArrayDeque<IncludeInfo>(targets);
|
||||
targets.clear();
|
||||
HashSet<IncludeInfo> seen = new HashSet<IncludeInfo>();
|
||||
HashSet<IncludeInfo> processed = new HashSet<IncludeInfo>();
|
||||
if (!forcedReplacement)
|
||||
seen.add(source); // Don't allow mapping to itself.
|
||||
int iterationsWithoutProgress = 0;
|
||||
processed.add(source); // Don't allow mapping to itself.
|
||||
HashSet<IncludeInfo> seenTargets = new HashSet<IncludeInfo>();
|
||||
IncludeInfo target;
|
||||
queueLoop: while ((target = queue.pollFirst()) != null) {
|
||||
if (seen.contains(target))
|
||||
if (processed.contains(target))
|
||||
continue;
|
||||
List<IncludeInfo> newTargets = map.get(target);
|
||||
if (newTargets != null) {
|
||||
queue.addFirst(target);
|
||||
boolean added = false;
|
||||
// Check if we saw the same target earlier to protect against an infinite loop.
|
||||
if (seenTargets.add(target)) {
|
||||
for (int i = newTargets.size(); --i >=0;) {
|
||||
IncludeInfo newTarget = newTargets.get(i);
|
||||
if (!seen.contains(newTarget)) {
|
||||
if (!processed.contains(newTarget)) {
|
||||
if (forcedReplacement && newTarget.equals(source)) {
|
||||
break queueLoop; // Leave the mapping empty.
|
||||
}
|
||||
|
@ -217,21 +222,21 @@ public class IncludeMap {
|
|||
added = true;
|
||||
}
|
||||
}
|
||||
// The second condition protects against an infinite loop.
|
||||
if (!added || ++iterationsWithoutProgress >= map.size()) {
|
||||
}
|
||||
if (!added) {
|
||||
target = queue.pollFirst();
|
||||
targets.add(target);
|
||||
if (forcedReplacement)
|
||||
break;
|
||||
seen.add(target);
|
||||
iterationsWithoutProgress = 0;
|
||||
processed.add(target);
|
||||
seenTargets.clear();
|
||||
}
|
||||
} else {
|
||||
targets.add(target);
|
||||
if (forcedReplacement)
|
||||
break;
|
||||
seen.add(target);
|
||||
iterationsWithoutProgress = 0;
|
||||
processed.add(target);
|
||||
seenTargets.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue