1
0
Fork 0
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:
Markus Schorn 2007-07-12 15:49:40 +00:00
parent 39b2ea6eb4
commit 849223972d
5 changed files with 150 additions and 106 deletions

View file

@ -69,7 +69,7 @@ public class IScannerInfoPluginTest extends FileBasePluginTest {
c = new CompleteParseBaseTest.FullParseCallback(); c = new CompleteParseBaseTest.FullParseCallback();
InputStream stream = code.getContents(); InputStream stream = code.getContents();
IParser parser = ParserFactory.createParser( 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 ParserMode.COMPLETE_PARSE, language, c, new NullLogService(), null ), c, ParserMode.COMPLETE_PARSE, language, null
); );
stream.close(); stream.close();
@ -87,9 +87,9 @@ public class IScannerInfoPluginTest extends FileBasePluginTest {
IFile imacroFile = importFile( "imacros.h", imacroContent ); //$NON-NLS-1$ IFile imacroFile = importFile( "imacros.h", imacroContent ); //$NON-NLS-1$
String code = "int x = ONE;\n"; //$NON-NLS-1$ String code = "int x = ONE;\n"; //$NON-NLS-1$
IFile sourceCode = importFile( "source.cpp", code ); //$NON-NLS-1$ IFile sourceCode = importFile( "source.cpp", code ); //$NON-NLS-1$
String [] imacroz = new String[1]; String[] isp= {imacroFile.getParent().getLocation().toString()};
imacroz[0] = imacroFile.getFullPath().toOSString(); String[] imacroz= {imacroFile.getName()};
IScannerInfo scannerInfo = new ExtendedScannerInfo( Collections.EMPTY_MAP, EMPTY_STRING_ARRAY, imacroz, EMPTY_STRING_ARRAY ); IScannerInfo scannerInfo = new ExtendedScannerInfo( Collections.EMPTY_MAP, isp, imacroz, EMPTY_STRING_ARRAY );
Iterator i = parse( sourceCode, ParserLanguage.C, scannerInfo ).getDeclarations(); Iterator i = parse( sourceCode, ParserLanguage.C, scannerInfo ).getDeclarations();
assertTrue( i.hasNext() ); assertTrue( i.hasNext() );
IASTVariable x = (IASTVariable) i.next(); IASTVariable x = (IASTVariable) i.next();
@ -106,9 +106,9 @@ public class IScannerInfoPluginTest extends FileBasePluginTest {
IFile inclFile = importFile( "includeMe.h", inclContent ); //$NON-NLS-1$ IFile inclFile = importFile( "includeMe.h", inclContent ); //$NON-NLS-1$
String code = "int y = x;\n"; //$NON-NLS-1$ String code = "int y = x;\n"; //$NON-NLS-1$
IFile sourceCode = importFile( "source.cpp", code ); //$NON-NLS-1$ IFile sourceCode = importFile( "source.cpp", code ); //$NON-NLS-1$
String [] includez = new String[1]; String[] isp= {inclFile.getParent().getLocation().toString()};
includez[0] = inclFile.getFullPath().toOSString(); String [] includez = {inclFile.getName()};
IScannerInfo scannerInfo = new ExtendedScannerInfo( Collections.EMPTY_MAP, EMPTY_STRING_ARRAY, EMPTY_STRING_ARRAY, includez ); IScannerInfo scannerInfo = new ExtendedScannerInfo( Collections.EMPTY_MAP, isp, EMPTY_STRING_ARRAY, includez );
Iterator i = parse( sourceCode, ParserLanguage.C, scannerInfo ).getDeclarations(); Iterator i = parse( sourceCode, ParserLanguage.C, scannerInfo ).getDeclarations();
assertTrue( i.hasNext() ); assertTrue( i.hasNext() );
assertTrue(i.next() instanceof IASTVariable ); assertTrue(i.next() instanceof IASTVariable );

View file

@ -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 // #define macro164500 1
// #undef macro164500 // #undef macro164500
// #define macro164500 2 // #define macro164500 2

View file

@ -37,6 +37,8 @@ import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile; 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.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.resources.ResourcesPlugin;
@ -223,23 +225,31 @@ public class TestSourceReader {
final IFile result[] = new IFile[1]; final IFile result[] = new IFile[1];
ws.run(new IWorkspaceRunnable() { ws.run(new IWorkspaceRunnable() {
public void run(IProgressMonitor monitor) throws CoreException { public void run(IProgressMonitor monitor) throws CoreException {
//Obtain file handle //Obtain file handle
IFile file = container.getFile(filePath); IFile file = container.getFile(filePath);
InputStream stream = new ByteArrayInputStream(contents.getBytes()); InputStream stream = new ByteArrayInputStream(contents.getBytes());
//Create file input stream //Create file input stream
if (file.exists()) { if (file.exists()) {
long timestamp= file.getLocalTimeStamp(); long timestamp= file.getLocalTimeStamp();
file.setContents(stream, false, false, new NullProgressMonitor()); file.setContents(stream, false, false, new NullProgressMonitor());
if (file.getLocalTimeStamp() == timestamp) { if (file.getLocalTimeStamp() == timestamp) {
file.setLocalTimeStamp(timestamp+1000); file.setLocalTimeStamp(timestamp+1000);
} }
} }
else { else {
file.create(stream, false, new NullProgressMonitor()); createFolders(file);
} file.create(stream, true, new NullProgressMonitor());
}
result[0]= file; 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); }, null);
return result[0]; return result[0];
} }

View file

@ -19,7 +19,6 @@ import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.Map; import java.util.Map;
import org.eclipse.cdt.core.dom.ast.IASTProblem; 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.CharArrayUtils;
import org.eclipse.cdt.core.parser.util.CharTable; 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.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.KeywordSets;
import org.eclipse.cdt.internal.core.parser.token.SimpleToken; 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 CharArrayObjectMap definitions = new CharArrayObjectMap(512);
protected String[] stdIncludePaths; protected String[] includePaths;
protected String[] locIncludePaths = null; protected String[] quoteIncludePaths;
/** Set of already included files */ /** Set of already included files */
protected CharArraySet includedFiles= new CharArraySet(32); protected CharArraySet includedFiles= new CharArraySet(32);
@ -196,8 +194,6 @@ abstract class BaseScanner implements IScanner {
protected ParserMode parserMode; protected ParserMode parserMode;
protected Iterator preIncludeFiles = EmptyIterator.EMPTY_ITERATOR;
protected boolean isInitialized = false; protected boolean isInitialized = false;
protected boolean macroFilesInitialized = false; protected boolean macroFilesInitialized = false;
@ -259,9 +255,7 @@ abstract class BaseScanner implements IScanner {
} }
} }
} }
stdIncludePaths = info.getIncludePaths(); includePaths= quoteIncludePaths= info.getIncludePaths();
} }
/** /**
@ -284,33 +278,51 @@ abstract class BaseScanner implements IScanner {
*/ */
protected void extendedScannerInfoSetup(CodeReader reader, IScannerInfo info) { protected void extendedScannerInfoSetup(CodeReader reader, IScannerInfo info) {
IExtendedScannerInfo einfo = (IExtendedScannerInfo) info; IExtendedScannerInfo einfo = (IExtendedScannerInfo) info;
if (einfo.getMacroFiles() != null) // setup separate include path for quote includes.
for (int i = 0; i < einfo.getMacroFiles().length; ++i) { String[] qip= einfo.getLocalIncludePath();
CodeReader r = createReaderDuple(einfo.getMacroFiles()[i]); if (qip != null && qip.length > 0) {
if (r == null) quoteIncludePaths= new String[qip.length + includePaths.length];
continue; System.arraycopy(qip, 0, quoteIncludePaths, 0, qip.length);
pushContext(r.buffer, r); System.arraycopy(includePaths, 0, quoteIncludePaths, qip.length, includePaths.length);
while (true) { }
try {
nextToken(); //
} catch (EndOfFileException e) { final String[] macroFiles = einfo.getMacroFiles();
finished = false; if (macroFiles != null) {
break; 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 {
nextToken();
} catch (EndOfFileException e) {
finished = false;
break;
}
}
} }
} }
}
macroFilesInitialized = true; 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); pushContext(reader.buffer, reader);
while (preIncludeFiles.hasNext()) final String[] preIncludeFiles= einfo.getIncludeFiles();
pushForcedInclusion(); 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; isInitialized = true;
} }
@ -413,27 +425,6 @@ abstract class BaseScanner implements IScanner {
return result; 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) { public IMacro addDefinition(char[] key, char[] value) {
int idx = CharArrayUtils.indexOf('(', key); int idx = CharArrayUtils.indexOf('(', key);
if (idx == -1) { if (idx == -1) {
@ -493,7 +484,7 @@ abstract class BaseScanner implements IScanner {
* @see org.eclipse.cdt.core.parser.IScanner#getIncludePaths() * @see org.eclipse.cdt.core.parser.IScanner#getIncludePaths()
*/ */
public String[] getIncludePaths() { public String[] getIncludePaths() {
return stdIncludePaths; return includePaths;
} }
/* /*
@ -1947,7 +1938,8 @@ abstract class BaseScanner implements IScanner {
else { else {
CodeReader reader= null; CodeReader reader= null;
if (active) { 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) { if (reader != null) {
final Object inc = createInclusionConstruct( final Object inc = createInclusionConstruct(
fileNameArray, reader.filename, local, startOffset, startingLineNumber, fileNameArray, reader.filename, local, startOffset, startingLineNumber,
@ -1972,50 +1964,36 @@ abstract class BaseScanner implements IScanner {
// default: do nothing // default: do nothing
} }
private CodeReader findInclusion(final String filename, final boolean local, final boolean include_next) { private CodeReader findInclusion(final String filename, final boolean quoteInclude,
return (CodeReader) findInclusion(filename, local, include_next, createCodeReaderTester); 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, protected Object findInclusion(final String filename, final boolean quoteInclude,
final IIncludeFileTester tester) { final boolean includeNext, final File currentDirectory, final IIncludeFileTester tester) {
Object reader = null; Object reader = null;
// filename is an absolute path or it is a Linux absolute path on a windows machine // 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$ if (new File(filename).isAbsolute() || filename.startsWith("/")) { //$NON-NLS-1$
return tester.checkFile( EMPTY_STRING, filename ); return tester.checkFile( EMPTY_STRING, filename );
} }
File currentDirectory = null; if (currentDirectory != null && quoteInclude && !includeNext) {
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) {
// Check to see if we find a match in the current directory // Check to see if we find a match in the current directory
if (currentDirectory != null) { String absolutePath = currentDirectory.getAbsolutePath();
String absolutePath = currentDirectory.getAbsolutePath(); reader = tester.checkFile(absolutePath, filename);
reader = tester.checkFile(absolutePath, filename); if (reader != null) {
if (reader != null) { return reader;
return reader; }
}
}
} }
// if we're not include_next, then we are looking for the first occurrence of // 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 // the file, otherwise, we ignore all the paths before the current directory
String [] includePathsToUse = stdIncludePaths; String[] includePathsToUse = quoteInclude ? quoteIncludePaths : includePaths;
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);
}
if (includePathsToUse != null ) { if (includePathsToUse != null ) {
int startpos = 0; int startpos = 0;
if (include_next) if (includeNext && currentDirectory != null) {
startpos = findIncludePos(includePathsToUse, currentDirectory) + 1; startpos = findIncludePos(includePathsToUse, currentDirectory) + 1;
}
for (int i = startpos; i < includePathsToUse.length; ++i) { for (int i = startpos; i < includePathsToUse.length; ++i) {
reader = tester.checkFile(includePathsToUse[i], filename); reader = tester.checkFile(includePathsToUse[i], filename);
if (reader != null) { if (reader != null) {

View file

@ -190,7 +190,8 @@ public class DOMScanner extends BaseScanner {
int startOffset, int nameOffset, int nameEndOffset, int endOffset, int startingLineNumber, int startOffset, int nameOffset, int nameEndOffset, int endOffset, int startingLineNumber,
int nameLine, int endLine) { int nameLine, int endLine) {
char[] pchars= null; 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 (path != null) {
if (codeReaderFactory instanceof IIndexBasedCodeReaderFactory) { if (codeReaderFactory instanceof IIndexBasedCodeReaderFactory) {
// fast indexer // fast indexer