1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 369770: Allow suppressing use of directory of current file for resolving includes (effect of option -I-).

This commit is contained in:
Markus Schorn 2012-07-24 10:09:25 +02:00
parent 7162e19924
commit ecdf231dbc
6 changed files with 119 additions and 30 deletions

View file

@ -278,4 +278,31 @@ public class InclusionTests extends PreprocessorTestsBase {
validateInteger("1");
validateEOF();
}
// #include "test.h"
public void testSuppressingUseOfCurrentFileDirectory() throws Exception {
String content= getAboveComment();
importFolder("f1");
IFolder inc = importFolder("f1/inc");
importFile("f1/test.h", "1");
importFile("f1/inc/test.h", "2");
IFile base = importFile("f1/base.cpp", getAboveComment());
String[] path = {inc.getLocation().toFile().toString()};
IScannerInfo scannerInfo = new ExtendedScannerInfo(Collections.EMPTY_MAP, path, new String[]{}, null);
FileContent reader= FileContent.create(base);
initializeScanner(reader, ParserLanguage.C, ParserMode.COMPLETE_PARSE, scannerInfo);
validateInteger("1");
validateEOF();
path = new String[] {inc.getLocation().toFile().toString(), "-"}; // Suppress use of current file directory
scannerInfo = new ExtendedScannerInfo(Collections.EMPTY_MAP, path, new String[]{}, null);
reader= FileContent.create(base);
initializeScanner(reader, ParserLanguage.C, ParserMode.COMPLETE_PARSE, scannerInfo);
validateInteger("2");
validateEOF();
}
}

View file

@ -6,13 +6,13 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Rational Software - Initial API and implementation
* John Camelon, IBM Rational Software - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.parser;
/**
* @author jcamelon
*
* Extension to {@link IScannerInfo}, allows for providing additional preprocessor options.
*/
public interface IExtendedScannerInfo extends IScannerInfo {
@ -31,6 +31,10 @@ public interface IExtendedScannerInfo extends IScannerInfo {
/**
* Return an array of paths that is searched after the current directory, when an include directive
* with double-quotes is processed.
* <p>
* In order to suppress the use of the directory of the current file (side effect of gcc option
* -I-) you can pass '-' as one of the include paths. Other than that, the '-' will not have an
* effect, in particular it will not split the include path as the -I- option would do.
*/
public String [] getLocalIncludePath();
}

View file

@ -31,6 +31,11 @@ public interface IScannerInfo {
* Returns an array of paths that are searched when processing an include directive.
* see {@link IExtendedScannerInfo#getLocalIncludePath()}
* <p>
* In order to suppress the use of the directory of the current file (side effect of gcc option
* -I-) you can pass '-' as one of the include paths. Other than that, the '-' will not have an
* effect, in particular it will not split the include path as the -I- option would do. To achieve
* that, use {@link IExtendedScannerInfo#getLocalIncludePath()}.
* <p>
* In order to handle framework includes used on Apple Computers you can make use of
* the two variables: '__framework__' and '__header__'.
* <br> E.g.: /System/Library/Frameworks/__framework__.framework/Headers/__header__,

View file

@ -14,6 +14,7 @@
package org.eclipse.cdt.internal.core.parser.scanner;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
@ -225,7 +226,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
final private AbstractParserLogService fLog;
final private InternalFileContentProvider fFileContentProvider;
private IIncludeFileResolutionHeuristics fIncludeFileResolutionHeuristics;
private final IIncludeFileResolutionHeuristics fIncludeFileResolutionHeuristics;
private final ExpressionEvaluator fExpressionEvaluator;
private final MacroDefinitionParser fMacroDefinitionParser;
private final MacroExpander fMacroExpander;
@ -235,7 +236,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
final private char[] fAdditionalNumericLiteralSuffixes;
final private CharArrayIntMap fKeywords;
final private CharArrayIntMap fPPKeywords;
private IncludeSearchPathElement[] fIncludeSearchPath;
private final IncludeSearchPath fIncludeSearchPath;
private String[][] fPreIncludedFiles= null;
private int fContentAssistLimit= -1;
@ -397,27 +398,36 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
return array == null ? CharArrayUtils.EMPTY_CHAR_ARRAY : array;
}
public static IncludeSearchPathElement[] configureIncludeSearchPath(File directory, IScannerInfo info) {
IncludeSearchPathElement[] includeSearchPath = null;
String[] searchPath= info.getIncludePaths();
int idx= 0;
public static IncludeSearchPath configureIncludeSearchPath(File directory, IScannerInfo info) {
boolean inhibitUseOfCurrentFileDirectory= false;
List<IncludeSearchPathElement> elements = new ArrayList<IncludeSearchPathElement>();
// Quote includes first
if (info instanceof IExtendedScannerInfo) {
final IExtendedScannerInfo einfo= (IExtendedScannerInfo) info;
final String[] quoteIncludeSearchPath= einfo.getLocalIncludePath();
if (quoteIncludeSearchPath != null && quoteIncludeSearchPath.length > 0) {
includeSearchPath= new IncludeSearchPathElement[quoteIncludeSearchPath.length + searchPath.length];
for (String path : quoteIncludeSearchPath) {
includeSearchPath[idx++]= new IncludeSearchPathElement(makeAbsolute(directory, path), true);
final String[] paths= einfo.getLocalIncludePath();
if (paths != null) {
for (String path : paths) {
if ("-".equals(path)) { //$NON-NLS-1$
inhibitUseOfCurrentFileDirectory= true;
} else {
elements.add(new IncludeSearchPathElement(makeAbsolute(directory, path), true));
}
}
}
if (includeSearchPath == null) {
includeSearchPath= new IncludeSearchPathElement[searchPath.length];
}
for (String path : searchPath) {
includeSearchPath[idx++]= new IncludeSearchPathElement(makeAbsolute(directory, path), false);
// Regular includes
String[] paths= info.getIncludePaths();
if (paths != null) {
for (String path : paths) {
if ("-".equals(path)) { //$NON-NLS-1$
inhibitUseOfCurrentFileDirectory= true;
} else {
elements.add(new IncludeSearchPathElement(makeAbsolute(directory, path), false));
}
return includeSearchPath;
}
}
return new IncludeSearchPath(elements, inhibitUseOfCurrentFileDirectory);
}
private static String makeAbsolute(File directory, String includePath) {
@ -1074,8 +1084,8 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
return tester.checkFile(absoluteInclusionPath, false, null);
}
if (currentFile != null && quoteInclude && !includeNext) {
// Check to see if we find a match in the current directory
if (currentFile != null && quoteInclude && !includeNext && !fIncludeSearchPath.isInhibitUseOfCurrentFileDirectory()) {
// Check to see if we find a match in the directory of the current file
final File currentDir= new File(currentFile).getParentFile();
if (currentDir != null) {
final String fileLocation = ScannerUtility.createReconciledPath(
@ -1103,7 +1113,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
}
}
for (IncludeSearchPathElement path : fIncludeSearchPath) {
for (IncludeSearchPathElement path : fIncludeSearchPath.getElements()) {
if (searchAfter != null) {
if (searchAfter.equals(path)) {
searchAfter= null;
@ -1146,7 +1156,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
}
private IncludeSearchPathElement findFileInIncludePath(String file, String includeDirective) {
for (IncludeSearchPathElement path : fIncludeSearchPath) {
for (IncludeSearchPathElement path : fIncludeSearchPath.getElements()) {
String fileLocation = path.getLocation(includeDirective);
if (file.equals(fileLocation)) {
return path;

View file

@ -0,0 +1,42 @@
/*******************************************************************************
* Copyright (c) 2009 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
import java.util.List;
/**
* Represents the include search path
*/
public final class IncludeSearchPath {
private final boolean fInhibitUseOfCurrentFileDirectory;
private final IncludeSearchPathElement[] fElements;
IncludeSearchPath(List<IncludeSearchPathElement> elements, boolean inhibitUseOfCurrentFileDirectory) {
fElements= elements.toArray(new IncludeSearchPathElement[elements.size()]);
fInhibitUseOfCurrentFileDirectory= inhibitUseOfCurrentFileDirectory;
}
/**
* @return the elements of the include search path.
*/
public IncludeSearchPathElement[] getElements() {
return fElements;
}
/**
* @return whether the use of the directory of the current file is inhibited.
*/
public boolean isInhibitUseOfCurrentFileDirectory() {
return fInhibitUseOfCurrentFileDirectory;
}
}

View file

@ -33,6 +33,7 @@ import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.internal.core.model.ExternalTranslationUnit;
import org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor;
import org.eclipse.cdt.internal.core.parser.scanner.IncludeSearchPath;
import org.eclipse.cdt.internal.core.parser.scanner.IncludeSearchPathElement;
import org.eclipse.cdt.internal.core.parser.scanner.ScannerUtility;
import org.eclipse.cdt.internal.core.pdom.IndexerProgress;
@ -199,7 +200,7 @@ public class PDOMUpdateTask implements IPDOMIndexerTask {
try {
String filePath = IndexLocationFactory.getAbsolutePath(file.getLocation()).toOSString();
long fileReadTime = file.getSourceReadTime();
IncludeSearchPathElement[] includeSearchPath =
IncludeSearchPath includeSearchPath =
CPreprocessor.configureIncludeSearchPath(new File(filePath).getParentFile(), scannerInfo);
for (IIndexInclude include : file.getIncludes()) {
if (!include.isResolved() && include.isActive() &&
@ -214,7 +215,7 @@ public class PDOMUpdateTask implements IPDOMIndexerTask {
}
private boolean canResolveInclude(IIndexInclude include, String currentFile, long timestamp,
IncludeSearchPathElement[] includeSearchPath,
IncludeSearchPath includeSearchPath,
ProjectIndexerIncludeResolutionHeuristics includeResolutionHeuristics) throws CoreException {
String includeName = include.getFullName();
String filePath = CPreprocessor.getAbsoluteInclusionPath(includeName, currentFile);
@ -222,7 +223,7 @@ public class PDOMUpdateTask implements IPDOMIndexerTask {
return true;
}
if (currentFile != null && !include.isSystemInclude()) {
if (currentFile != null && !include.isSystemInclude() && !includeSearchPath.isInhibitUseOfCurrentFileDirectory()) {
// Check to see if we find a match in the current directory
final File currentDir= new File(currentFile).getParentFile();
if (currentDir != null) {
@ -237,7 +238,7 @@ public class PDOMUpdateTask implements IPDOMIndexerTask {
// This simplification may produce false positives, but by checking file modification time
// we guarantee that any false positive won't be produced again when this task runs
// next time.
for (IncludeSearchPathElement path : includeSearchPath) {
for (IncludeSearchPathElement path : includeSearchPath.getElements()) {
if (!include.isSystemInclude() || !path.isForQuoteIncludesOnly()) {
filePath = path.getLocation(includeName);
if (filePath != null && fileIsNotOlderThanTimestamp(filePath, timestamp)) {