From 7c92e3e070fe96238cb24cc6bc6b4f453d33bdda Mon Sep 17 00:00:00 2001 From: Andrew Gvozdev Date: Sun, 16 Dec 2012 23:52:16 -0500 Subject: [PATCH] bug 396411: JUnit failure: cdt.managedbuilder.core.tests.ManagedBuildCoreTests20.testScannerInfoInterface --- .../core/tests/ManagedBuildCoreTests20.java | 15 ++-- .../MBSLanguageSettingsProvider.java | 19 +++++ .../LanguageSettingsScannerInfoProvider.java | 74 ++++++++++--------- 3 files changed, 68 insertions(+), 40 deletions(-) diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildCoreTests20.java b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildCoreTests20.java index db1e40dd63d..1df00d08f76 100644 --- a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildCoreTests20.java +++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildCoreTests20.java @@ -250,8 +250,9 @@ public class ManagedBuildCoreTests20 extends TestCase { toOSLocation("/usr/include"), toOSLocation("/opt/gnome/include"), toOSLocation("C:\\home\\tester/include"), - // relative paths make 2 entries - buildCWD.append("../includes").toOSString(), + // relative paths from MBS will make 3 entries + project.getLocation().append("includes").toOSString(), + buildCWD.append("includes").toOSString(), toOSString("includes"), "/usr/gnu/include", // Not converted to OS string due to being flagged as ICSettingEntry.RESOLVED }; @@ -260,10 +261,14 @@ public class ManagedBuildCoreTests20 extends TestCase { expectedPaths = new String[] { toOSLocation("/usr/include"), toOSLocation("/opt/gnome/include"), - buildCWD.append("C:\\home\\tester/include").toOSString(), // added on Unix being relative path + // on unix "C:\\home\\tester/include" is relative path + // looks like nonsense but has to be this way as MBS converts entry to keep "Sub Config/C:\\home\\tester/include" in its storage + project.getLocation().append("Sub Config/C:\\home\\tester/include").toOSString(), + buildCWD.append("Sub Config/C:\\home\\tester/include").toOSString(), toOSString("Sub Config/C:\\home\\tester/include"), - // relative paths make 2 entries - buildCWD.append("../includes").toOSString(), + // relative paths from MBS will make 3 entries + project.getLocation().append("includes").toOSString(), + buildCWD.append("includes").toOSString(), toOSString("includes"), "/usr/gnu/include", // Not converted to OS string due to being flagged as ICSettingEntry.RESOLVED }; diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/language/settings/providers/MBSLanguageSettingsProvider.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/language/settings/providers/MBSLanguageSettingsProvider.java index 24616f8eeb7..e529345df1d 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/language/settings/providers/MBSLanguageSettingsProvider.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/language/settings/providers/MBSLanguageSettingsProvider.java @@ -22,11 +22,16 @@ import org.eclipse.cdt.core.settings.model.ICFileDescription; import org.eclipse.cdt.core.settings.model.ICFolderDescription; import org.eclipse.cdt.core.settings.model.ICLanguageSetting; import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry; +import org.eclipse.cdt.core.settings.model.ICPathEntry; import org.eclipse.cdt.core.settings.model.ICResourceDescription; import org.eclipse.cdt.core.settings.model.ICSettingBase; +import org.eclipse.cdt.core.settings.model.util.CDataUtil; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.variables.IStringVariableManager; +import org.eclipse.core.variables.VariablesPlugin; /** * Implementation of language settings provider for CDT Managed Build System. @@ -62,6 +67,20 @@ public class MBSLanguageSettingsProvider extends AbstractExecutableExtensionBase if ((kindsBits & kind) != 0) { List additions = langSetting.getSettingEntriesList(kind); for (ICLanguageSettingEntry entry : additions) { + if (entry instanceof ICPathEntry) { + // have to use getName() rather than getLocation() and not use IPath operations to avoid collapsing ".." + String pathStr = ((ICPathEntry) entry).getName(); + if (!new Path(pathStr).isAbsolute()) { + // We need to add project-rooted entry for relative path as MBS counts it this way in some UI + // The relative entry below also should be added for indexer to resolve from source file locations + IStringVariableManager mngr = VariablesPlugin.getDefault().getStringVariableManager(); + String projectRootedPath = mngr.generateVariableExpression("workspace_loc", rc.getProject().getName()) + Path.SEPARATOR + pathStr; //$NON-NLS-1$ + ICLanguageSettingEntry projectRootedEntry = (ICLanguageSettingEntry) CDataUtil.createEntry(kind, projectRootedPath, projectRootedPath, null, entry.getFlags()); + if (! list.contains(projectRootedEntry)) { + list.add(projectRootedEntry); + } + } + } if (! list.contains(entry)) { list.add(entry); } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsScannerInfoProvider.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsScannerInfoProvider.java index 302ec73ecd0..86748454c45 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsScannerInfoProvider.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsScannerInfoProvider.java @@ -30,10 +30,10 @@ import org.eclipse.cdt.core.parser.ExtendedScannerInfo; import org.eclipse.cdt.core.parser.IScannerInfo; import org.eclipse.cdt.core.parser.IScannerInfoChangeListener; import org.eclipse.cdt.core.parser.IScannerInfoProvider; -import org.eclipse.cdt.core.settings.model.ACPathEntry; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry; import org.eclipse.cdt.core.settings.model.ICMacroEntry; +import org.eclipse.cdt.core.settings.model.ICPathEntry; import org.eclipse.cdt.core.settings.model.ICProjectDescription; import org.eclipse.cdt.core.settings.model.ICSettingEntry; import org.eclipse.cdt.core.settings.model.util.CDataUtil; @@ -129,17 +129,15 @@ public class LanguageSettingsScannerInfoProvider implements IScannerInfoProvider return new ExtendedScannerInfo(definedMacros, includePaths, macroFiles, includeFiles, includePathsLocal); } - private IPath expandVariables(IPath path, ICConfigurationDescription cfgDescription) { - ICdtVariableManager varManager = CCorePlugin.getDefault().getCdtVariableManager(); - String pathStr = path.toString(); + private String expandVariables(String pathStr, ICConfigurationDescription cfgDescription) { try { + ICdtVariableManager varManager = CCorePlugin.getDefault().getCdtVariableManager(); pathStr = varManager.resolveValue(pathStr, "", null, cfgDescription); //$NON-NLS-1$ - } catch (CdtVariableException e) { + } catch (Exception e) { // Swallow exceptions but also log them CCorePlugin.log(e); } - IPath resolvedLoc = new Path(pathStr); - return resolvedLoc; + return pathStr; } /** @@ -178,7 +176,7 @@ public class LanguageSettingsScannerInfoProvider implements IScannerInfoProvider * Resolve location to file system location in a configuration context. * Resolving includes replacing build/environment variables with values, making relative path absolute etc. * - * @param location - location to resolve. If relative, it is taken to be rooted in project directory. + * @param location - location to resolve. If relative, it is taken to be rooted in build working directory. * @param cfgDescription - the configuration context. * @return resolved file system location. */ @@ -209,22 +207,27 @@ public class LanguageSettingsScannerInfoProvider implements IScannerInfoProvider } if (!locPath.isAbsolute()) { - ICProjectDescription projectDescription = cfgDescription.getProjectDescription(); - if (projectDescription != null) { - IProject project = projectDescription.getProject(); - if (project != null) { - IPath projectLocation = project.getLocation(); - if (projectLocation != null) { - // again, we avoid using org.eclipse.core.runtime.Path for manipulations being careful - // to preserve "../" segments and not let collapsing them which is not correct for symbolic links. - location = projectLocation.addTrailingSeparator().toOSString() + locPath.toOSString(); - } - } - } + // consider relative path to be from build working directory + IPath buildCWD = getBuildCWD(cfgDescription); + // again, we avoid using org.eclipse.core.runtime.Path for manipulations being careful + // to preserve "../" segments and not let collapsing them which is not correct for symbolic links. + location = buildCWD.addTrailingSeparator().toOSString() + location; } return location; } + /** + * Convert path delimiters to OS representation avoiding using org.eclipse.core.runtime.Path + * being careful to preserve "../" segments and not let collapsing them which is not correct for symbolic links. + */ + private String toOSString(String loc) { + // use OS file separators (i.e. '\' on Windows) + if (java.io.File.separatorChar != IPath.SEPARATOR) { + loc = loc.replace(IPath.SEPARATOR, java.io.File.separatorChar); + } + return loc; + } + /** * Convert the path entries to absolute file system locations represented as String array. * Resolve the entries which are not resolved. @@ -236,7 +239,7 @@ public class LanguageSettingsScannerInfoProvider implements IScannerInfoProvider private String[] convertToLocations(LinkedHashSet entriesPath, ICConfigurationDescription cfgDescription) { List locations = new ArrayList(entriesPath.size()); for (ICLanguageSettingEntry entry : entriesPath) { - ACPathEntry entryPath = (ACPathEntry)entry; + ICPathEntry entryPath = (ICPathEntry)entry; if (entryPath.isValueWorkspacePath()) { ICLanguageSettingEntry[] entries = new ICLanguageSettingEntry[] {entry}; if (!entry.isResolved()) { @@ -244,7 +247,7 @@ public class LanguageSettingsScannerInfoProvider implements IScannerInfoProvider } for (ICLanguageSettingEntry resolved : entries) { - IPath loc = ((ACPathEntry) resolved).getLocation(); + IPath loc = ((ICPathEntry) resolved).getLocation(); if (loc != null) { if (checkBit(resolved.getFlags(), ICSettingEntry.FRAMEWORKS_MAC)) { // handle frameworks, see IScannerInfo.getIncludePaths() @@ -256,24 +259,25 @@ public class LanguageSettingsScannerInfoProvider implements IScannerInfoProvider } } } else { - String locStr = entryPath.getName(); + // have to use getName() rather than getLocation() to avoid collapsing ".." + String loc = entryPath.getName(); if (entryPath.isResolved()) { - locations.add(locStr); + locations.add(loc); } else { - locStr = resolveEntry(locStr, cfgDescription); - if (locStr!=null) { + loc = resolveEntry(loc, cfgDescription); + if (loc != null) { if (checkBit(entryPath.getFlags(), ICSettingEntry.FRAMEWORKS_MAC)) { // handle frameworks, see IScannerInfo.getIncludePaths() - locations.add(locStr+FRAMEWORK_HEADERS_INCLUDE); - locations.add(locStr+FRAMEWORK_PRIVATE_HEADERS_INCLUDE); + locations.add(toOSString(loc + FRAMEWORK_HEADERS_INCLUDE)); + locations.add(toOSString(loc + FRAMEWORK_PRIVATE_HEADERS_INCLUDE)); } else { - locations.add(locStr); - // add relative paths again for indexer to resolve from source file location - IPath unresolvedPath = entryPath.getLocation(); - if (!unresolvedPath.isAbsolute()) { - IPath expandedPath = expandVariables(unresolvedPath, cfgDescription); - if (!expandedPath.isEmpty() && !expandedPath.isAbsolute()) { - locations.add(expandedPath.toOSString()); + locations.add(toOSString(loc)); + String unresolvedPath = entryPath.getName(); + if (!new Path(unresolvedPath).isAbsolute()) { + // add relative paths again for indexer to resolve from source file location + String expandedPath = expandVariables(unresolvedPath, cfgDescription); + if (!expandedPath.isEmpty() && !new Path(expandedPath).isAbsolute()) { + locations.add(toOSString(expandedPath)); } } }