diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/GCCBuildCommandParserTest.java b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/GCCBuildCommandParserTest.java index 3ddb9454292..a3176ef29ac 100644 --- a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/GCCBuildCommandParserTest.java +++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/language/settings/providers/tests/GCCBuildCommandParserTest.java @@ -1391,6 +1391,9 @@ public class GCCBuildCommandParserTest extends BaseTestCase { IFolder folder=ResourceHelper.createFolder(project, "Local/BuildDir/Folder"); IFolder folder2=ResourceHelper.createFolder(project, "Local/BuildDir/Folder2"); IFile file=ResourceHelper.createFile(project, "Local/BuildDir/file.cpp"); + IFile incFile1=ResourceHelper.createFile(project, "Local/BuildDir/include.file1"); + IFile incFile2=ResourceHelper.createFile(project, "Local/BuildDir/include.file2"); + ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true); String languageId = ls.getLanguageId(); @@ -1410,6 +1413,10 @@ public class GCCBuildCommandParserTest extends BaseTestCase { + " -I../BuildDir/Folder2" + " -I/BuildDir/MissingFolder" + " -I../BuildDir/MissingFolder2" + + " -include /BuildDir/include.file1" + + " -include ../BuildDir/include.file2" + + " -include /BuildDir/missing.include.file" + + " -include ../BuildDir/missing.include.file" + " /BuildDir/file.cpp"); parser.shutdown(); @@ -1420,6 +1427,10 @@ public class GCCBuildCommandParserTest extends BaseTestCase { assertEquals(new CIncludePathEntry(folder2.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(2)); assertEquals(new CIncludePathEntry("/BuildDir/MissingFolder", 0), entries.get(3)); assertEquals(new CIncludePathEntry(buildDir.getFullPath().append("MissingFolder2"), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(4)); + assertEquals(new CIncludeFileEntry(incFile1.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(5)); + assertEquals(new CIncludeFileEntry(incFile2.getFullPath(), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(6)); + assertEquals(new CIncludeFileEntry("/BuildDir/missing.include.file", 0), entries.get(7)); + assertEquals(new CIncludeFileEntry(buildDir.getFullPath().append("missing.include.file"), ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED), entries.get(8)); } /** @@ -2070,24 +2081,26 @@ public class GCCBuildCommandParserTest extends BaseTestCase { IFile file=ResourceHelper.createFile(project, "file.cpp"); ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project); ICConfigurationDescription cfgDescription = cfgDescriptions[0]; - + ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true); String languageId = ls.getLanguageId(); - + // create GCCBuildCommandParser GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT, true); parser.setResourceScope(AbstractBuildCommandParser.ResourceScope.PROJECT); - + // parse line parser.startup(cfgDescription, null); parser.processLine("gcc " + "-I/path0 " + + "-IC:/path1 " + "/absolute/path/file.cpp"); parser.shutdown(); - + // check entries List entries = parser.getSettingEntries(cfgDescription, project, languageId); assertEquals(new CIncludePathEntry("/path0", 0), entries.get(0)); + assertEquals(new CIncludePathEntry("C:/path1", 0), entries.get(1)); } /** @@ -2099,17 +2112,56 @@ public class GCCBuildCommandParserTest extends BaseTestCase { GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getRawProvider(wspProvider); parser.setResourceScope(AbstractBuildCommandParser.ResourceScope.PROJECT); parser.clear(); - + // parse line parser.startup(null, null); parser.processLine("gcc " + "-I/path0 " + "/absolute/path/file.cpp"); parser.shutdown(); - + // check entries List entries = parser.getSettingEntries(null, null, LANG_CPP); assertEquals(new CIncludePathEntry("/path0", 0), entries.get(0)); } - + + /** + * Parsing of file being compiled outside of workspace saving entries at project scope. + */ + public void testFileAbsolutePath_ProjectLevel_bug404125() throws Exception { + // Create model project and accompanied descriptions + String projectName = getName(); + IProject project = ResourceHelper.createCDTProjectWithConfig(projectName); + IFile file=ResourceHelper.createFile(project, "file.c"); + ICConfigurationDescription[] cfgDescriptions = getConfigurationDescriptions(project); + ICConfigurationDescription cfgDescription = cfgDescriptions[0]; + + ICLanguageSetting ls = cfgDescription.getLanguageSettingForFile(file.getProjectRelativePath(), true); + String languageId = ls.getLanguageId(); + + // create GCCBuildCommandParser + GCCBuildCommandParser parser = (GCCBuildCommandParser) LanguageSettingsManager.getExtensionProviderCopy(GCC_BUILD_COMMAND_PARSER_EXT, true); + parser.setResourceScope(AbstractBuildCommandParser.ResourceScope.PROJECT); + + ErrorParserManager epm = new ErrorParserManager(project, null); + // Set build directory + epm.pushDirectoryURI(project.getLocationURI()); + + // parse line + parser.startup(cfgDescription, epm); + parser.processLine("gcc " + // In scenario from bug 404125 drive letter somehow induced path to be appended to project directory + + "-IC:/path " + + "-I.. " + + "/absolute/path/file.c"); + parser.shutdown(); + + // check entries + List entries = parser.getSettingEntries(cfgDescription, project, languageId); + assertEquals(new CIncludePathEntry("C:/path", 0), entries.get(0)); + assertEquals(new CIncludePathEntry(project.getLocation().removeLastSegments(1), 0), entries.get(1)); + assertEquals(2, entries.size()); + } + + } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractLanguageSettingsOutputScanner.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractLanguageSettingsOutputScanner.java index 0e718103ca1..0f415e7972c 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractLanguageSettingsOutputScanner.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/language/settings/providers/AbstractLanguageSettingsOutputScanner.java @@ -460,12 +460,12 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett if (optionParser.parseOption(option)) { ICLanguageSettingEntry entry = null; if (isResolvingPaths && (optionParser.isForFile() || optionParser.isForFolder())) { - URI baseURI = buildDirURI; - if (mappedRootURI != null) { - if (buildDirURI != null && !new Path(optionParser.parsedName).isAbsolute()) { + URI baseURI = mappedRootURI; + if (buildDirURI != null && !new Path(optionParser.parsedName).isAbsolute()) { + if (mappedRootURI != null) { baseURI = efsProvider.append(mappedRootURI, buildDirURI.getPath()); } else { - baseURI = mappedRootURI; + baseURI = buildDirURI; } } entry = createResolvedPathEntry(optionParser, optionParser.parsedName, 0, baseURI); @@ -644,21 +644,21 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett } /** - * Find resource in the workspace for a given URI with a preference for the resource + * Find file resource in the workspace for a given URI with a preference for the resource * to reside in the given project. */ - private static IResource findFileForLocationURI(URI uri, IProject preferredProject) { + private static IResource findFileForLocationURI(URI uri, IProject preferredProject, boolean checkExistence) { IResource sourceFile = null; IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); IResource[] resources = root.findFilesForLocationURI(uri); - if (resources.length > 0) { - sourceFile = resources[0]; - if (preferredProject != null) { - for (IResource rc : resources) { - if (rc.getProject().equals(preferredProject)) { - sourceFile = rc; - break; - } + for (IResource rc : resources) { + if (!checkExistence || rc.isAccessible()) { + if (rc.getProject().equals(preferredProject)) { + sourceFile = rc; + break; + } + if (sourceFile == null) { + sourceFile = rc; } } } @@ -669,11 +669,11 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett * Return a resource in workspace corresponding the given folder {@link URI} preferable residing in * the provided project. */ - private static IResource findContainerForLocationURI(URI uri, IProject preferredProject) { + private static IResource findContainerForLocationURI(URI uri, IProject preferredProject, boolean checkExistence) { IResource resource = null; IResource[] resources = ResourcesPlugin.getWorkspace().getRoot().findContainersForLocationURI(uri); for (IResource rc : resources) { - if ((rc instanceof IProject || rc instanceof IFolder)) { // treat IWorkspaceRoot as non-workspace path + if ((rc instanceof IProject || rc instanceof IFolder) && (!checkExistence || rc.isAccessible())) { // treat IWorkspaceRoot as non-workspace path if (rc.getProject().equals(preferredProject)) { resource = rc; break; @@ -704,7 +704,7 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett // try to find absolute path in the workspace if (sourceFile == null && new Path(parsedResourceName).isAbsolute()) { URI uri = org.eclipse.core.filesystem.URIUtil.toURI(parsedResourceName); - sourceFile = findFileForLocationURI(uri, currentProject); + sourceFile = findFileForLocationURI(uri, currentProject, /*checkExistence*/ true); } // try last known current working directory from build output @@ -712,7 +712,7 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett URI cwdURI = cwdTracker.getWorkingDirectoryURI(); if (cwdURI != null) { URI uri = efsProvider.append(cwdURI, parsedResourceName); - sourceFile = findFileForLocationURI(uri, currentProject); + sourceFile = findFileForLocationURI(uri, currentProject, /*checkExistence*/ true); } } @@ -722,7 +722,7 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett if (builderCWD!=null) { IPath path = builderCWD.append(parsedResourceName); URI uri = org.eclipse.core.filesystem.URIUtil.toURI(path); - sourceFile = findFileForLocationURI(uri, currentProject); + sourceFile = findFileForLocationURI(uri, currentProject, /*checkExistence*/ true); } } @@ -1002,12 +1002,12 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett URI uri = determineMappedURI(parsedPath, baseURI); IResource rc = null; - // Try to resolve in the workspace + // Try to resolve as existing resource in the workspace if (uri != null && uri.isAbsolute()) { if (optionParser.isForFolder()) { - rc = findContainerForLocationURI(uri, currentProject); + rc = findContainerForLocationURI(uri, currentProject, /*checkExistence*/ true); } else if (optionParser.isForFile()) { - rc = findFileForLocationURI(uri, currentProject); + rc = findFileForLocationURI(uri, currentProject, /*checkExistence*/ true); } if (rc != null) { resolvedPath = rc.getFullPath().toString(); @@ -1015,11 +1015,11 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett } } - // Try to resolve on the file-system + // Try to resolve as existing file/folder on the file-system + IPath fileSystemLocation = getFilesystemLocation(uri); if (resolvedPath == null) { - IPath path = getFilesystemLocation(uri); - if (path != null && new File(path.toString()).exists()) { - resolvedPath = path.toString(); + if (fileSystemLocation != null && new File(fileSystemLocation.toString()).exists()) { + resolvedPath = fileSystemLocation.toString(); resolvedFlag = flag; } if (resolvedPath == null) { @@ -1034,13 +1034,30 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett resolvedFlag = flag | ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED; } } - if (resolvedPath == null && path != null) { - resolvedPath = path.toString(); - resolvedFlag = flag; + } + + // Try to resolve in the workspace as a handle + if (resolvedPath == null) { + if (uri != null && uri.isAbsolute()) { + if (optionParser.isForFolder()) { + rc = findContainerForLocationURI(uri, currentProject, /*checkExistence*/ false); + } else if (optionParser.isForFile()) { + rc = findFileForLocationURI(uri, currentProject, /*checkExistence*/ false); + } + if (rc != null) { + resolvedPath = rc.getFullPath().toString(); + resolvedFlag = flag | ICSettingEntry.VALUE_WORKSPACE_PATH | ICSettingEntry.RESOLVED; + } } } - // if cannot resolve keep parsed path + // Try to set to file-system location if available + if (resolvedPath == null && fileSystemLocation != null) { + resolvedPath = fileSystemLocation.toString(); + resolvedFlag = flag; + } + + // If still cannot resolve keep parsed path if (resolvedPath == null) { resolvedPath = parsedPath; resolvedFlag = flag;