mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-04 14:55:41 +02:00
Fix for 160281, files included via -include not searched on the include path.
This commit is contained in:
parent
39b2ea6eb4
commit
849223972d
5 changed files with 150 additions and 106 deletions
|
@ -69,7 +69,7 @@ public class IScannerInfoPluginTest extends FileBasePluginTest {
|
|||
c = new CompleteParseBaseTest.FullParseCallback();
|
||||
InputStream stream = code.getContents();
|
||||
IParser parser = ParserFactory.createParser(
|
||||
ParserFactory.createScanner( new CodeReader( code.getLocation().toOSString(), stream ), scannerInfo, //$NON-NLS-1$
|
||||
ParserFactory.createScanner( new CodeReader( code.getLocation().toOSString(), stream ), scannerInfo,
|
||||
ParserMode.COMPLETE_PARSE, language, c, new NullLogService(), null ), c, ParserMode.COMPLETE_PARSE, language, null
|
||||
);
|
||||
stream.close();
|
||||
|
@ -87,9 +87,9 @@ public class IScannerInfoPluginTest extends FileBasePluginTest {
|
|||
IFile imacroFile = importFile( "imacros.h", imacroContent ); //$NON-NLS-1$
|
||||
String code = "int x = ONE;\n"; //$NON-NLS-1$
|
||||
IFile sourceCode = importFile( "source.cpp", code ); //$NON-NLS-1$
|
||||
String [] imacroz = new String[1];
|
||||
imacroz[0] = imacroFile.getFullPath().toOSString();
|
||||
IScannerInfo scannerInfo = new ExtendedScannerInfo( Collections.EMPTY_MAP, EMPTY_STRING_ARRAY, imacroz, EMPTY_STRING_ARRAY );
|
||||
String[] isp= {imacroFile.getParent().getLocation().toString()};
|
||||
String[] imacroz= {imacroFile.getName()};
|
||||
IScannerInfo scannerInfo = new ExtendedScannerInfo( Collections.EMPTY_MAP, isp, imacroz, EMPTY_STRING_ARRAY );
|
||||
Iterator i = parse( sourceCode, ParserLanguage.C, scannerInfo ).getDeclarations();
|
||||
assertTrue( i.hasNext() );
|
||||
IASTVariable x = (IASTVariable) i.next();
|
||||
|
@ -106,9 +106,9 @@ public class IScannerInfoPluginTest extends FileBasePluginTest {
|
|||
IFile inclFile = importFile( "includeMe.h", inclContent ); //$NON-NLS-1$
|
||||
String code = "int y = x;\n"; //$NON-NLS-1$
|
||||
IFile sourceCode = importFile( "source.cpp", code ); //$NON-NLS-1$
|
||||
String [] includez = new String[1];
|
||||
includez[0] = inclFile.getFullPath().toOSString();
|
||||
IScannerInfo scannerInfo = new ExtendedScannerInfo( Collections.EMPTY_MAP, EMPTY_STRING_ARRAY, EMPTY_STRING_ARRAY, includez );
|
||||
String[] isp= {inclFile.getParent().getLocation().toString()};
|
||||
String [] includez = {inclFile.getName()};
|
||||
IScannerInfo scannerInfo = new ExtendedScannerInfo( Collections.EMPTY_MAP, isp, EMPTY_STRING_ARRAY, includez );
|
||||
Iterator i = parse( sourceCode, ParserLanguage.C, scannerInfo ).getDeclarations();
|
||||
assertTrue( i.hasNext() );
|
||||
assertTrue(i.next() instanceof IASTVariable );
|
||||
|
|
|
@ -341,6 +341,61 @@ public class IndexBugsTests extends BaseTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
public void test160281_1() throws Exception {
|
||||
waitForIndexer();
|
||||
IFile include= TestSourceReader.createFile(fCProject.getProject(), "inc/test160281_1.h", "");
|
||||
TestScannerProvider.sIncludes= new String[]{include.getLocation().removeLastSegments(1).toString()};
|
||||
TestScannerProvider.sIncludeFiles= new String[]{include.getName()};
|
||||
IFile file= TestSourceReader.createFile(fCProject.getProject(), "test160281_1.cpp", "");
|
||||
TestSourceReader.waitUntilFileIsIndexed(fIndex, file, INDEX_WAIT_TIME);
|
||||
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
IIndexFile ifile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(file));
|
||||
assertNotNull(ifile);
|
||||
IIndexInclude[] includes= ifile.getIncludes();
|
||||
assertEquals(1, includes.length);
|
||||
IIndexInclude i= includes[0];
|
||||
assertEquals(file.getLocationURI(), i.getIncludedByLocation().getURI());
|
||||
assertEquals(include.getLocationURI(), i.getIncludesLocation().getURI());
|
||||
assertEquals(true, i.isSystemInclude());
|
||||
assertEquals(0, i.getNameOffset());
|
||||
assertEquals(0, i.getNameLength());
|
||||
}
|
||||
finally {
|
||||
fIndex.releaseReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
public void test160281_2() throws Exception {
|
||||
waitForIndexer();
|
||||
IFile include= TestSourceReader.createFile(fCProject.getProject(), "inc/test160281_2.h", "#define X y\n");
|
||||
TestScannerProvider.sIncludes= new String[]{include.getLocation().removeLastSegments(1).toString()};
|
||||
TestScannerProvider.sMacroFiles= new String[]{include.getName()};
|
||||
IFile file= TestSourceReader.createFile(fCProject.getProject(), "test160281_2.cpp", "int X;");
|
||||
TestSourceReader.waitUntilFileIsIndexed(fIndex, file, INDEX_WAIT_TIME);
|
||||
|
||||
fIndex.acquireReadLock();
|
||||
try {
|
||||
IIndexFile ifile= fIndex.getFile(IndexLocationFactory.getWorkspaceIFL(file));
|
||||
assertNotNull(ifile);
|
||||
IIndexInclude[] includes= ifile.getIncludes();
|
||||
assertEquals(1, includes.length);
|
||||
IIndexInclude i= includes[0];
|
||||
assertEquals(file.getLocationURI(), i.getIncludedByLocation().getURI());
|
||||
assertEquals(include.getLocationURI(), i.getIncludesLocation().getURI());
|
||||
assertEquals(true, i.isSystemInclude());
|
||||
assertEquals(0, i.getNameOffset());
|
||||
assertEquals(0, i.getNameLength());
|
||||
IIndexBinding[] bindings= fIndex.findBindings("y".toCharArray(), IndexFilter.ALL, NPM);
|
||||
assertEquals(1, bindings.length);
|
||||
assertTrue(bindings[0] instanceof IVariable);
|
||||
}
|
||||
finally {
|
||||
fIndex.releaseReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
// #define macro164500 1
|
||||
// #undef macro164500
|
||||
// #define macro164500 2
|
||||
|
|
|
@ -37,6 +37,8 @@ import org.eclipse.cdt.core.model.ICProject;
|
|||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.core.resources.IContainer;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IFolder;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.resources.IWorkspace;
|
||||
import org.eclipse.core.resources.IWorkspaceRunnable;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
|
@ -236,10 +238,18 @@ public class TestSourceReader {
|
|||
}
|
||||
}
|
||||
else {
|
||||
file.create(stream, false, new NullProgressMonitor());
|
||||
createFolders(file);
|
||||
file.create(stream, true, new NullProgressMonitor());
|
||||
}
|
||||
result[0]= file;
|
||||
}
|
||||
private void createFolders(IResource res) throws CoreException {
|
||||
IContainer container= res.getParent();
|
||||
if (!container.exists() && container instanceof IFolder) {
|
||||
createFolders(container);
|
||||
((IFolder) container).create(true, true, new NullProgressMonitor());
|
||||
}
|
||||
}
|
||||
}, null);
|
||||
return result[0];
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ import java.io.IOException;
|
|||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTProblem;
|
||||
|
@ -49,7 +48,6 @@ import org.eclipse.cdt.core.parser.util.CharArraySet;
|
|||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||
import org.eclipse.cdt.core.parser.util.CharTable;
|
||||
import org.eclipse.cdt.internal.core.parser.ast.ASTCompletionNode;
|
||||
import org.eclipse.cdt.internal.core.parser.ast.EmptyIterator;
|
||||
import org.eclipse.cdt.internal.core.parser.token.KeywordSets;
|
||||
import org.eclipse.cdt.internal.core.parser.token.SimpleToken;
|
||||
|
||||
|
@ -146,8 +144,8 @@ abstract class BaseScanner implements IScanner {
|
|||
|
||||
protected CharArrayObjectMap definitions = new CharArrayObjectMap(512);
|
||||
|
||||
protected String[] stdIncludePaths;
|
||||
protected String[] locIncludePaths = null;
|
||||
protected String[] includePaths;
|
||||
protected String[] quoteIncludePaths;
|
||||
|
||||
/** Set of already included files */
|
||||
protected CharArraySet includedFiles= new CharArraySet(32);
|
||||
|
@ -196,8 +194,6 @@ abstract class BaseScanner implements IScanner {
|
|||
|
||||
protected ParserMode parserMode;
|
||||
|
||||
protected Iterator preIncludeFiles = EmptyIterator.EMPTY_ITERATOR;
|
||||
|
||||
protected boolean isInitialized = false;
|
||||
protected boolean macroFilesInitialized = false;
|
||||
|
||||
|
@ -259,9 +255,7 @@ abstract class BaseScanner implements IScanner {
|
|||
}
|
||||
}
|
||||
}
|
||||
stdIncludePaths = info.getIncludePaths();
|
||||
|
||||
|
||||
includePaths= quoteIncludePaths= info.getIncludePaths();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -284,11 +278,20 @@ abstract class BaseScanner implements IScanner {
|
|||
*/
|
||||
protected void extendedScannerInfoSetup(CodeReader reader, IScannerInfo info) {
|
||||
IExtendedScannerInfo einfo = (IExtendedScannerInfo) info;
|
||||
if (einfo.getMacroFiles() != null)
|
||||
for (int i = 0; i < einfo.getMacroFiles().length; ++i) {
|
||||
CodeReader r = createReaderDuple(einfo.getMacroFiles()[i]);
|
||||
if (r == null)
|
||||
continue;
|
||||
// setup separate include path for quote includes.
|
||||
String[] qip= einfo.getLocalIncludePath();
|
||||
if (qip != null && qip.length > 0) {
|
||||
quoteIncludePaths= new String[qip.length + includePaths.length];
|
||||
System.arraycopy(qip, 0, quoteIncludePaths, 0, qip.length);
|
||||
System.arraycopy(includePaths, 0, quoteIncludePaths, qip.length, includePaths.length);
|
||||
}
|
||||
|
||||
//
|
||||
final String[] macroFiles = einfo.getMacroFiles();
|
||||
if (macroFiles != null) {
|
||||
for (int i = 0; i < macroFiles.length; ++i) {
|
||||
CodeReader r= findInclusion(macroFiles[i], true, false, null);
|
||||
if (r != null) {
|
||||
pushContext(r.buffer, r);
|
||||
while (true) {
|
||||
try {
|
||||
|
@ -299,18 +302,27 @@ abstract class BaseScanner implements IScanner {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macroFilesInitialized = true;
|
||||
if (parserMode != ParserMode.QUICK_PARSE && einfo.getIncludeFiles() != null
|
||||
&& einfo.getIncludeFiles().length > 0)
|
||||
preIncludeFiles = Arrays.asList(einfo.getIncludeFiles()).iterator();
|
||||
|
||||
locIncludePaths = einfo.getLocalIncludePath();
|
||||
pushContext(reader.buffer, reader);
|
||||
|
||||
while (preIncludeFiles.hasNext())
|
||||
pushForcedInclusion();
|
||||
|
||||
final String[] preIncludeFiles= einfo.getIncludeFiles();
|
||||
if (parserMode != ParserMode.QUICK_PARSE && preIncludeFiles != null) {
|
||||
for (int i = 0; i < preIncludeFiles.length; i++) {
|
||||
final String file = preIncludeFiles[i];
|
||||
CodeReader r= findInclusion(file, true, false, null);
|
||||
if (r != null) {
|
||||
int o = getCurrentOffset() + 1;
|
||||
int l = getLineNumber(o);
|
||||
Object incObj = createInclusionConstruct(file.toCharArray(), r.filename, false, o,
|
||||
l, o, o, l, o, l, true);
|
||||
InclusionData d = new InclusionData(r, incObj, false);
|
||||
pushContext(r.buffer, d);
|
||||
}
|
||||
}
|
||||
}
|
||||
isInitialized = true;
|
||||
}
|
||||
|
||||
|
@ -413,27 +425,6 @@ abstract class BaseScanner implements IScanner {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected void pushForcedInclusion() {
|
||||
CodeReader r = null;
|
||||
while (r == null) {
|
||||
if (preIncludeFiles.hasNext())
|
||||
r = createReaderDuple((String) preIncludeFiles.next());
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (r == null)
|
||||
return;
|
||||
int o = getCurrentOffset() + 1;
|
||||
int l = getLineNumber(o);
|
||||
Object i = createInclusionConstruct(r.filename, r.filename, false, o,
|
||||
l, o, o, l, o, l, true);
|
||||
InclusionData d = new InclusionData(r, i, false);
|
||||
pushContext(r.buffer, d);
|
||||
}
|
||||
|
||||
public IMacro addDefinition(char[] key, char[] value) {
|
||||
int idx = CharArrayUtils.indexOf('(', key);
|
||||
if (idx == -1) {
|
||||
|
@ -493,7 +484,7 @@ abstract class BaseScanner implements IScanner {
|
|||
* @see org.eclipse.cdt.core.parser.IScanner#getIncludePaths()
|
||||
*/
|
||||
public String[] getIncludePaths() {
|
||||
return stdIncludePaths;
|
||||
return includePaths;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1947,7 +1938,8 @@ abstract class BaseScanner implements IScanner {
|
|||
else {
|
||||
CodeReader reader= null;
|
||||
if (active) {
|
||||
reader= findInclusion(filename, local, include_next);
|
||||
final File currentDir= local || include_next ? new File(String.valueOf(getCurrentFilename())).getParentFile() : null;
|
||||
reader= findInclusion(filename, local, include_next, currentDir);
|
||||
if (reader != null) {
|
||||
final Object inc = createInclusionConstruct(
|
||||
fileNameArray, reader.filename, local, startOffset, startingLineNumber,
|
||||
|
@ -1972,50 +1964,36 @@ abstract class BaseScanner implements IScanner {
|
|||
// default: do nothing
|
||||
}
|
||||
|
||||
private CodeReader findInclusion(final String filename, final boolean local, final boolean include_next) {
|
||||
return (CodeReader) findInclusion(filename, local, include_next, createCodeReaderTester);
|
||||
private CodeReader findInclusion(final String filename, final boolean quoteInclude,
|
||||
final boolean includeNext, final File currentDir) {
|
||||
return (CodeReader) findInclusion(filename, quoteInclude, includeNext, currentDir, createCodeReaderTester);
|
||||
}
|
||||
|
||||
protected Object findInclusion(final String filename, final boolean local, final boolean include_next,
|
||||
final IIncludeFileTester tester) {
|
||||
protected Object findInclusion(final String filename, final boolean quoteInclude,
|
||||
final boolean includeNext, final File currentDirectory, final IIncludeFileTester tester) {
|
||||
Object reader = null;
|
||||
// filename is an absolute path or it is a Linux absolute path on a windows machine
|
||||
if (new File(filename).isAbsolute() || filename.startsWith("/")) { //$NON-NLS-1$
|
||||
return tester.checkFile( EMPTY_STRING, filename );
|
||||
}
|
||||
|
||||
File currentDirectory = null;
|
||||
if (local || include_next) {
|
||||
// if the include is enclosed in quotes OR we are in an include_next
|
||||
// then we need to know what the current directory is!
|
||||
File file = new File(String.valueOf(getCurrentFilename()));
|
||||
currentDirectory = file.getParentFile();
|
||||
}
|
||||
|
||||
if (local && !include_next) {
|
||||
if (currentDirectory != null && quoteInclude && !includeNext) {
|
||||
// Check to see if we find a match in the current directory
|
||||
if (currentDirectory != null) {
|
||||
String absolutePath = currentDirectory.getAbsolutePath();
|
||||
reader = tester.checkFile(absolutePath, filename);
|
||||
if (reader != null) {
|
||||
return reader;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we're not include_next, then we are looking for the first occurrence of
|
||||
// the file, otherwise, we ignore all the paths before the current directory
|
||||
String [] includePathsToUse = stdIncludePaths;
|
||||
if( local && locIncludePaths != null && locIncludePaths.length > 0 ) {
|
||||
includePathsToUse = new String[locIncludePaths.length + stdIncludePaths.length];
|
||||
System.arraycopy(locIncludePaths, 0, includePathsToUse, 0, locIncludePaths.length);
|
||||
System.arraycopy(stdIncludePaths, 0, includePathsToUse, locIncludePaths.length, stdIncludePaths.length);
|
||||
}
|
||||
|
||||
String[] includePathsToUse = quoteInclude ? quoteIncludePaths : includePaths;
|
||||
if (includePathsToUse != null ) {
|
||||
int startpos = 0;
|
||||
if (include_next)
|
||||
if (includeNext && currentDirectory != null) {
|
||||
startpos = findIncludePos(includePathsToUse, currentDirectory) + 1;
|
||||
}
|
||||
for (int i = startpos; i < includePathsToUse.length; ++i) {
|
||||
reader = tester.checkFile(includePathsToUse[i], filename);
|
||||
if (reader != null) {
|
||||
|
|
|
@ -190,7 +190,8 @@ public class DOMScanner extends BaseScanner {
|
|||
int startOffset, int nameOffset, int nameEndOffset, int endOffset, int startingLineNumber,
|
||||
int nameLine, int endLine) {
|
||||
char[] pchars= null;
|
||||
String path= (String) findInclusion(new String(filename), local, include_next, createPathTester);
|
||||
final File currentDir= local || include_next ? new File(String.valueOf(getCurrentFilename())).getParentFile() : null;
|
||||
String path= (String) findInclusion(new String(filename), local, include_next, currentDir, createPathTester);
|
||||
if (path != null) {
|
||||
if (codeReaderFactory instanceof IIndexBasedCodeReaderFactory) {
|
||||
// fast indexer
|
||||
|
|
Loading…
Add table
Reference in a new issue