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"); validateInteger("1");
validateEOF(); 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 * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * 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; package org.eclipse.cdt.core.parser;
/** /**
* @author jcamelon * Extension to {@link IScannerInfo}, allows for providing additional preprocessor options.
*
*/ */
public interface IExtendedScannerInfo extends IScannerInfo { 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 * Return an array of paths that is searched after the current directory, when an include directive
* with double-quotes is processed. * 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(); 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. * Returns an array of paths that are searched when processing an include directive.
* see {@link IExtendedScannerInfo#getLocalIncludePath()} * see {@link IExtendedScannerInfo#getLocalIncludePath()}
* <p> * <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 * In order to handle framework includes used on Apple Computers you can make use of
* the two variables: '__framework__' and '__header__'. * the two variables: '__framework__' and '__header__'.
* <br> E.g.: /System/Library/Frameworks/__framework__.framework/Headers/__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; package org.eclipse.cdt.internal.core.parser.scanner;
import java.io.File; import java.io.File;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -225,7 +226,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
final private AbstractParserLogService fLog; final private AbstractParserLogService fLog;
final private InternalFileContentProvider fFileContentProvider; final private InternalFileContentProvider fFileContentProvider;
private IIncludeFileResolutionHeuristics fIncludeFileResolutionHeuristics; private final IIncludeFileResolutionHeuristics fIncludeFileResolutionHeuristics;
private final ExpressionEvaluator fExpressionEvaluator; private final ExpressionEvaluator fExpressionEvaluator;
private final MacroDefinitionParser fMacroDefinitionParser; private final MacroDefinitionParser fMacroDefinitionParser;
private final MacroExpander fMacroExpander; private final MacroExpander fMacroExpander;
@ -235,7 +236,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
final private char[] fAdditionalNumericLiteralSuffixes; final private char[] fAdditionalNumericLiteralSuffixes;
final private CharArrayIntMap fKeywords; final private CharArrayIntMap fKeywords;
final private CharArrayIntMap fPPKeywords; final private CharArrayIntMap fPPKeywords;
private IncludeSearchPathElement[] fIncludeSearchPath; private final IncludeSearchPath fIncludeSearchPath;
private String[][] fPreIncludedFiles= null; private String[][] fPreIncludedFiles= null;
private int fContentAssistLimit= -1; private int fContentAssistLimit= -1;
@ -397,27 +398,36 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
return array == null ? CharArrayUtils.EMPTY_CHAR_ARRAY : array; return array == null ? CharArrayUtils.EMPTY_CHAR_ARRAY : array;
} }
public static IncludeSearchPathElement[] configureIncludeSearchPath(File directory, IScannerInfo info) { public static IncludeSearchPath configureIncludeSearchPath(File directory, IScannerInfo info) {
IncludeSearchPathElement[] includeSearchPath = null; boolean inhibitUseOfCurrentFileDirectory= false;
String[] searchPath= info.getIncludePaths(); List<IncludeSearchPathElement> elements = new ArrayList<IncludeSearchPathElement>();
int idx= 0;
if (info instanceof IExtendedScannerInfo) { // Quote includes first
if (info instanceof IExtendedScannerInfo) {
final IExtendedScannerInfo einfo= (IExtendedScannerInfo) info; final IExtendedScannerInfo einfo= (IExtendedScannerInfo) info;
final String[] quoteIncludeSearchPath= einfo.getLocalIncludePath(); final String[] paths= einfo.getLocalIncludePath();
if (quoteIncludeSearchPath != null && quoteIncludeSearchPath.length > 0) { if (paths != null) {
includeSearchPath= new IncludeSearchPathElement[quoteIncludeSearchPath.length + searchPath.length]; for (String path : paths) {
for (String path : quoteIncludeSearchPath) { if ("-".equals(path)) { //$NON-NLS-1$
includeSearchPath[idx++]= new IncludeSearchPathElement(makeAbsolute(directory, path), true); inhibitUseOfCurrentFileDirectory= true;
} else {
elements.add(new IncludeSearchPathElement(makeAbsolute(directory, path), true));
}
} }
} }
} }
if (includeSearchPath == null) { // Regular includes
includeSearchPath= new IncludeSearchPathElement[searchPath.length]; String[] paths= info.getIncludePaths();
} if (paths != null) {
for (String path : searchPath) { for (String path : paths) {
includeSearchPath[idx++]= new IncludeSearchPathElement(makeAbsolute(directory, path), false); if ("-".equals(path)) { //$NON-NLS-1$
} inhibitUseOfCurrentFileDirectory= true;
return includeSearchPath; } else {
elements.add(new IncludeSearchPathElement(makeAbsolute(directory, path), false));
}
}
}
return new IncludeSearchPath(elements, inhibitUseOfCurrentFileDirectory);
} }
private static String makeAbsolute(File directory, String includePath) { 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); return tester.checkFile(absoluteInclusionPath, false, null);
} }
if (currentFile != null && quoteInclude && !includeNext) { if (currentFile != null && quoteInclude && !includeNext && !fIncludeSearchPath.isInhibitUseOfCurrentFileDirectory()) {
// Check to see if we find a match in the current directory // Check to see if we find a match in the directory of the current file
final File currentDir= new File(currentFile).getParentFile(); final File currentDir= new File(currentFile).getParentFile();
if (currentDir != null) { if (currentDir != null) {
final String fileLocation = ScannerUtility.createReconciledPath( 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 != null) {
if (searchAfter.equals(path)) { if (searchAfter.equals(path)) {
searchAfter= null; searchAfter= null;
@ -1146,7 +1156,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
} }
private IncludeSearchPathElement findFileInIncludePath(String file, String includeDirective) { private IncludeSearchPathElement findFileInIncludePath(String file, String includeDirective) {
for (IncludeSearchPathElement path : fIncludeSearchPath) { for (IncludeSearchPathElement path : fIncludeSearchPath.getElements()) {
String fileLocation = path.getLocation(includeDirective); String fileLocation = path.getLocation(includeDirective);
if (file.equals(fileLocation)) { if (file.equals(fileLocation)) {
return path; 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.core.parser.IScannerInfo;
import org.eclipse.cdt.internal.core.model.ExternalTranslationUnit; 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.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.IncludeSearchPathElement;
import org.eclipse.cdt.internal.core.parser.scanner.ScannerUtility; import org.eclipse.cdt.internal.core.parser.scanner.ScannerUtility;
import org.eclipse.cdt.internal.core.pdom.IndexerProgress; import org.eclipse.cdt.internal.core.pdom.IndexerProgress;
@ -199,7 +200,7 @@ public class PDOMUpdateTask implements IPDOMIndexerTask {
try { try {
String filePath = IndexLocationFactory.getAbsolutePath(file.getLocation()).toOSString(); String filePath = IndexLocationFactory.getAbsolutePath(file.getLocation()).toOSString();
long fileReadTime = file.getSourceReadTime(); long fileReadTime = file.getSourceReadTime();
IncludeSearchPathElement[] includeSearchPath = IncludeSearchPath includeSearchPath =
CPreprocessor.configureIncludeSearchPath(new File(filePath).getParentFile(), scannerInfo); CPreprocessor.configureIncludeSearchPath(new File(filePath).getParentFile(), scannerInfo);
for (IIndexInclude include : file.getIncludes()) { for (IIndexInclude include : file.getIncludes()) {
if (!include.isResolved() && include.isActive() && if (!include.isResolved() && include.isActive() &&
@ -214,7 +215,7 @@ public class PDOMUpdateTask implements IPDOMIndexerTask {
} }
private boolean canResolveInclude(IIndexInclude include, String currentFile, long timestamp, private boolean canResolveInclude(IIndexInclude include, String currentFile, long timestamp,
IncludeSearchPathElement[] includeSearchPath, IncludeSearchPath includeSearchPath,
ProjectIndexerIncludeResolutionHeuristics includeResolutionHeuristics) throws CoreException { ProjectIndexerIncludeResolutionHeuristics includeResolutionHeuristics) throws CoreException {
String includeName = include.getFullName(); String includeName = include.getFullName();
String filePath = CPreprocessor.getAbsoluteInclusionPath(includeName, currentFile); String filePath = CPreprocessor.getAbsoluteInclusionPath(includeName, currentFile);
@ -222,7 +223,7 @@ public class PDOMUpdateTask implements IPDOMIndexerTask {
return true; 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 // Check to see if we find a match in the current directory
final File currentDir= new File(currentFile).getParentFile(); final File currentDir= new File(currentFile).getParentFile();
if (currentDir != null) { if (currentDir != null) {
@ -237,7 +238,7 @@ public class PDOMUpdateTask implements IPDOMIndexerTask {
// This simplification may produce false positives, but by checking file modification time // 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 // we guarantee that any false positive won't be produced again when this task runs
// next time. // next time.
for (IncludeSearchPathElement path : includeSearchPath) { for (IncludeSearchPathElement path : includeSearchPath.getElements()) {
if (!include.isSystemInclude() || !path.isForQuoteIncludesOnly()) { if (!include.isSystemInclude() || !path.isForQuoteIncludesOnly()) {
filePath = path.getLocation(includeName); filePath = path.getLocation(includeName);
if (filePath != null && fileIsNotOlderThanTimestamp(filePath, timestamp)) { if (filePath != null && fileIsNotOlderThanTimestamp(filePath, timestamp)) {