diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugUtils.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugUtils.java index 0c607e563cb..22850a291de 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugUtils.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugUtils.java @@ -781,4 +781,79 @@ public class CDebugUtils { String customModel = System.getProperty(ICDebugConstants.PREF_TOGGLE_BREAKPOINT_MODEL_IDENTIFIER, null); return customModel != null && Boolean.valueOf(customModel); } + + /** + * Return value type for {@link CDebugUtils#getFileParts(String)} + * @since 8.0 + */ + public static class FileParts { + private String folder; + private String fileName; + private String extension; + + /** + * Returns the containing folder of the input file. Can be empty if the + * input file was a filename. + * + * @return containing folder + */ + public String getFolder() { + return folder; + } + + /** + * Returns the filename (after last slash) of the input file. Can be + * empty if input ended with a slash. + * + * @return file name + */ + public String getFileName() { + return fileName; + } + + /** + * Returns the extension of {@link #getFileName()} + * + * @return the extension + */ + public String getExtension() { + return extension; + } + + /** + * CDebugUtils.getFileParts(String) should be called to create FileParts. + */ + private FileParts() {} + } + + /** + * Split a Windows or Unix style path into its constituent parts. + * + * The split does not modify or canonicalize the individual parts of the + * file name. Nor does it convert between platforms. + * + * This method is useful for dealing with Windows paths when running on + * Linux and vice versa, it is also useful for non-canonical paths (ones + * with .. in them). + * + * @param file + * file name + * @return parts of a file + * @since 8.0 + */ + public static FileParts getFileParts(String file) { + FileParts parts = new FileParts(); + int lastSlash = Math.max(file.lastIndexOf("/"), file.lastIndexOf("\\")); //$NON-NLS-1$ //$NON-NLS-2$ + // lastSlash may be -1 if no separator found, that means the + // whole path is just a fileName and folder ends up as "" + parts.fileName = file.substring(lastSlash + 1); + parts.folder = file.substring(0, lastSlash + 1); + int lastDot = parts.fileName.lastIndexOf("."); //$NON-NLS-1$ + if (lastDot < 0) { + parts.extension = ""; //$NON-NLS-1$ + } else { + parts.extension = parts.fileName.substring(lastDot + 1); + } + return parts; + } } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/sourcelookup/MappingSourceContainer.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/sourcelookup/MappingSourceContainer.java index 763cf22edbd..3c0d4610c25 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/sourcelookup/MappingSourceContainer.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/sourcelookup/MappingSourceContainer.java @@ -202,7 +202,7 @@ public class MappingSourceContainer extends AbstractSourceContainer implements I MapEntrySourceContainer entry = (MapEntrySourceContainer) containers[i]; IPath local = entry.getLocalPath(); if (local.isPrefixOf(path)) { - result = entry.getBackendPath().append(path.removeFirstSegments(local.segmentCount())); + result = new Path(entry.getBackendPathStr()).append(path.removeFirstSegments(local.segmentCount())); break; } } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/MapEntrySourceContainer.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/MapEntrySourceContainer.java index 4840b39dabd..884f7034b5c 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/MapEntrySourceContainer.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/MapEntrySourceContainer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2014 QNX Software Systems and others. + * Copyright (c) 2004, 2015 QNX Software Systems 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 @@ -43,30 +43,32 @@ public class MapEntrySourceContainer extends AbstractSourceContainer { public static final String TYPE_ID = CDebugCorePlugin.getUniqueIdentifier() + ".containerType.mapEntry"; //$NON-NLS-1$ private IPath fLocalPath; - private IPath fBackendPath; + private String fBackendPathStr; - /** - * Constructor for MapEntrySourceContainer. + /** + * Constructor for MapEntrySourceContainer. */ public MapEntrySourceContainer() { - fBackendPath = Path.EMPTY; + fBackendPathStr = ""; //$NON-NLS-1$ fLocalPath = Path.EMPTY; } - /** - * Constructor for MapEntrySourceContainer. + /** + * Constructor for MapEntrySourceContainer. */ - public MapEntrySourceContainer(IPath backend, IPath local) { - fBackendPath = backend; + public MapEntrySourceContainer(String backendPathStr, IPath local) { + fBackendPathStr = backendPathStr; fLocalPath = local; } /** - * Creates an IPath from a string which may be a Win32 path.

+ * Creates an IPath from a string which may be a Win32 path. *

- * ("new Path(...)" won't work in Unix when using a Win32 path: the backslash - * separator and the device notation are completely munged.) + *

+ * ("new Path(...)" won't work in Unix when using a Win32 path: the + * backslash separator and the device notation are completely munged.) * Copied from org.eclipse.cdt.debug.edc.internal.PathUtils + * * @param path * @return converted string */ @@ -107,11 +109,36 @@ public class MapEntrySourceContainer extends AbstractSourceContainer { @Override public Object[] findSourceElements(String name) throws CoreException { - IPath path = createPath(name); - if (getBackendPath().isPrefixOf(path)) { - path = path.removeFirstSegments(getBackendPath().segmentCount()); - path = getLocalPath().append(path); + IPath path = null; + if (name != null) { + // First try the non-canonical comparison + final String backend = getBackendPathStr(); + if (name.toLowerCase().startsWith(backend.toLowerCase())) { + String suffix = name.substring(backend.length()); + // checkStartsWith only verifies that the paths are the same up + // to getBackend(), however if name=/hello2/a.c and backend=/hello + // then checkStartsWith will be true, so we have to further check + // that we are on a separator + if (backend.endsWith("/") || backend.endsWith("\\") || //$NON-NLS-1$ //$NON-NLS-2$ + suffix.startsWith("/") || suffix.startsWith("\\")) { //$NON-NLS-1$ //$NON-NLS-2$ + path = getLocalPath().append(suffix); + } + } + + // Then if we have not matched, try the legacy way of canonicalizing + // the paths and comparing them + if (path == null) { + IPath input = createPath(name); + IPath backendPath = createPath(backend); + if (backendPath.isPrefixOf(input)) { + IPath suffix = input.removeFirstSegments(backendPath.segmentCount()); + path = getLocalPath().append(suffix); + } + } + } + + if (path != null) { IFile[] wsFiles = ResourceLookup.findFilesForLocation(path); ArrayList list = new ArrayList(); for (int j = 0; j < wsFiles.length; ++j) { @@ -157,7 +184,7 @@ public class MapEntrySourceContainer extends AbstractSourceContainer { @Override public String getName() { - return MessageFormat.format("{0} - {1}", new Object[] { getBackendPath().toOSString(), getLocalPath().toOSString() }); //$NON-NLS-1$ + return MessageFormat.format("{0} - {1}", new Object[] { getBackendPathStr(), getLocalPath().toOSString() }); //$NON-NLS-1$ } @Override @@ -168,17 +195,17 @@ public class MapEntrySourceContainer extends AbstractSourceContainer { public IPath getLocalPath() { return fLocalPath; } - - public IPath getBackendPath() { - return fBackendPath; + + public String getBackendPathStr() { + return fBackendPathStr; } public void setLocalPath(IPath local) { fLocalPath = local; } - - public void setBackendPath(IPath backend) { - fBackendPath = backend; + + public void setBackendPathStr(String backendPathStr) { + fBackendPathStr = backendPathStr; } @Override @@ -186,10 +213,10 @@ public class MapEntrySourceContainer extends AbstractSourceContainer { if (!(o instanceof MapEntrySourceContainer)) return false; MapEntrySourceContainer entry = (MapEntrySourceContainer)o; - return (entry.getBackendPath().equals(getBackendPath()) && entry.getLocalPath().equals(getLocalPath())); + return (entry.getBackendPathStr().equals(getBackendPathStr()) && entry.getLocalPath().equals(getLocalPath())); } public MapEntrySourceContainer copy() { - return new MapEntrySourceContainer(fBackendPath, fLocalPath); + return new MapEntrySourceContainer(fBackendPathStr, fLocalPath); } } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/MapEntrySourceContainerType.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/MapEntrySourceContainerType.java index ba7ece1975f..6b5a296c210 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/MapEntrySourceContainerType.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/MapEntrySourceContainerType.java @@ -36,12 +36,14 @@ public class MapEntrySourceContainerType extends AbstractSourceContainerTypeDele if (node.getNodeType() == Node.ELEMENT_NODE) { Element element = (Element)node; if (ELEMENT_NAME.equals(element.getNodeName())) { - String path = element.getAttribute(BACKEND_PATH); - IPath backend = MapEntrySourceContainer.createPath(path); - if (!backend.isValidPath(path)) { + String backend = element.getAttribute(BACKEND_PATH); + if (backend == null || backend.isEmpty()) { abort(InternalSourceLookupMessages.MapEntrySourceContainerType_0, null); } - path = element.getAttribute(LOCAL_PATH); + String path = element.getAttribute(LOCAL_PATH); + if (path == null) { + abort(InternalSourceLookupMessages.MapEntrySourceContainerType_1, null); + } IPath local = new Path(path); if (!local.isValidPath(path)) { abort(InternalSourceLookupMessages.MapEntrySourceContainerType_1, null); @@ -62,7 +64,7 @@ public class MapEntrySourceContainerType extends AbstractSourceContainerTypeDele MapEntrySourceContainer entry = (MapEntrySourceContainer) container; Document document = newDocument(); Element element = document.createElement(ELEMENT_NAME); - element.setAttribute(BACKEND_PATH, entry.getBackendPath().toOSString()); + element.setAttribute(BACKEND_PATH, entry.getBackendPathStr()); element.setAttribute(LOCAL_PATH, entry.getLocalPath().toOSString()); document.appendChild(element); return serializeDocument(document); diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/SourceUtils.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/SourceUtils.java index e09de597936..2455781d8c1 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/SourceUtils.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/SourceUtils.java @@ -186,7 +186,7 @@ public class SourceUtils { IPath a = d.getAssociation(); if (a != null) { MappingSourceContainer mapping = new MappingSourceContainer(InternalSourceLookupMessages.SourceUtils_0 + (++mappingCount)); - mapping.addMapEntries(new MapEntrySourceContainer[] { new MapEntrySourceContainer(a, d.getDirectory()) }); + mapping.addMapEntries(new MapEntrySourceContainer[] { new MapEntrySourceContainer(a.toOSString(), d.getDirectory()) }); containers.add(mapping); } diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/sourcelookup/CSourceNotFoundEditor.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/sourcelookup/CSourceNotFoundEditor.java index ccbb41c5d40..e47cf0db573 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/sourcelookup/CSourceNotFoundEditor.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/sourcelookup/CSourceNotFoundEditor.java @@ -17,6 +17,7 @@ import java.util.Arrays; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.debug.core.CDebugCorePlugin; +import org.eclipse.cdt.debug.core.CDebugUtils; import org.eclipse.cdt.debug.core.sourcelookup.MappingSourceContainer; import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector; import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceNotFoundElement; @@ -205,7 +206,7 @@ public class CSourceNotFoundEditor extends CommonSourceNotFoundEditor { } } - private void addSourceMappingToDirector(IPath missingPath, IPath newSourcePath, AbstractSourceLookupDirector director) throws CoreException { + private void addSourceMappingToDirector(String missingPath, IPath newSourcePath, AbstractSourceLookupDirector director) throws CoreException { ArrayList containerList = new ArrayList(Arrays.asList(director.getSourceContainers())); MappingSourceContainer foundMappings = null; for (ISourceContainer container : containerList) { @@ -237,13 +238,13 @@ public class CSourceNotFoundEditor extends CommonSourceNotFoundEditor { * the location of the file locally; the user led us to it * @throws CoreException */ - private void addSourceMappingToCommon(IPath missingPath, IPath newSourcePath) throws CoreException { + private void addSourceMappingToCommon(String missingPath, IPath newSourcePath) throws CoreException { CSourceLookupDirector director = CDebugCorePlugin.getDefault().getCommonSourceLookupDirector(); addSourceMappingToDirector(missingPath, newSourcePath, director); CDebugCorePlugin.getDefault().savePluginPreferences(); } - private void addSourceMappingToLaunch(IPath missingPath, IPath newSourcePath) throws CoreException { + private void addSourceMappingToLaunch(String missingPath, IPath newSourcePath) throws CoreException { String memento = null; String type = null; @@ -270,26 +271,28 @@ public class CSourceNotFoundEditor extends CommonSourceNotFoundEditor { } } + protected void locateFile() { FileDialog dialog = new FileDialog(getEditorSite().getShell(), SWT.NONE); - IPath missingPath = MapEntrySourceContainer.createPath(missingFile); dialog.setFilterNames(new String[] {SourceLookupUIMessages.CSourceNotFoundEditor_2}); - dialog.setFilterExtensions(new String[] {"*." + missingPath.getFileExtension()}); //$NON-NLS-1$ + // We cannot use IPaths when manipulating the missingFile (aka compilation file name) otherwise + // we end up converting windows paths to Linux and/or other canonicalisation of the names + CDebugUtils.FileParts missingFileParts = CDebugUtils.getFileParts(missingFile); + dialog.setFilterExtensions(new String[] {"*." + missingFileParts.getExtension()}); //$NON-NLS-1$ String res = dialog.open(); if (res != null) { - Path newPath = new Path(res); - - if (newPath.lastSegment().equalsIgnoreCase(missingPath.lastSegment())) { - if (missingPath.segmentCount() > 1) { - IPath compPath = missingPath.removeLastSegments(1); - IPath newSourcePath = newPath.removeLastSegments(1); + CDebugUtils.FileParts resParts = CDebugUtils.getFileParts(res); + if (resParts.getFileName().toLowerCase().equals(missingFileParts.getFileName().toLowerCase())) { + String compPath = missingFileParts.getFolder(); + IPath newSourcePath = new Path(resParts.getFolder()); + if (compPath.length() > 0) { try { if (isDebugElement) addSourceMappingToLaunch(compPath, newSourcePath); else - addSourceMappingToCommon(compPath, newSourcePath); + addSourceMappingToCommon(compPath, newSourcePath); } catch (CoreException e) { - } + } } IWorkbenchPage page = getEditorSite().getPage(); diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/sourcelookup/MappingSourceContainerDialog.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/sourcelookup/MappingSourceContainerDialog.java index ee534ba8a2e..f3c109c3c71 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/sourcelookup/MappingSourceContainerDialog.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/sourcelookup/MappingSourceContainerDialog.java @@ -81,7 +81,7 @@ public class MappingSourceContainerDialog extends TitleAreaDialog { if (element instanceof MapEntrySourceContainer) { MapEntrySourceContainer entry = (MapEntrySourceContainer)element; if (CP_COMPILATION_PATH.equals(property)) - return entry.getBackendPath().toOSString(); + return entry.getBackendPathStr(); if (CP_FILE_SYSTEM_PATH.equals(property)) return entry.getLocalPath().toOSString(); } @@ -99,7 +99,7 @@ public class MappingSourceContainerDialog extends TitleAreaDialog { : (MapEntrySourceContainer)element; boolean isDirty = false; if (CP_COMPILATION_PATH.equals(property)) { - entry.setBackendPath(new Path((String)value)); + entry.setBackendPathStr((String)value); isDirty = true; } else if (CP_FILE_SYSTEM_PATH.equals(property)) { @@ -150,7 +150,7 @@ public class MappingSourceContainerDialog extends TitleAreaDialog { if (element instanceof MapEntrySourceContainer) { MapEntrySourceContainer entry = (MapEntrySourceContainer)element; if (columnIndex == 0) - return entry.getBackendPath().toOSString(); + return entry.getBackendPathStr(); if (columnIndex == 1) return entry.getLocalPath().toOSString(); } @@ -484,15 +484,11 @@ public class MappingSourceContainerDialog extends TitleAreaDialog { return; for (ISourceContainer c : containers) { MapEntrySourceContainer entry = (MapEntrySourceContainer)c; - IPath backendPath = entry.getBackendPath(); + String backendPath = entry.getBackendPathStr(); if (backendPath.isEmpty()) { setErrorMessage(SourceLookupUIMessages.PathMappingDialog_5); break; } - if (!backendPath.isValidPath(backendPath.toString())) { - setErrorMessage(SourceLookupUIMessages.PathMappingDialog_6); - break; - } IPath localPath = entry.getLocalPath(); if (localPath.isEmpty()) { setErrorMessage(SourceLookupUIMessages.PathMappingDialog_7); diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/sourcelookup/PathMappingDialog.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/sourcelookup/PathMappingDialog.java index 6e3c650dcee..9fb73b40e6a 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/sourcelookup/PathMappingDialog.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/sourcelookup/PathMappingDialog.java @@ -183,7 +183,7 @@ public class PathMappingDialog extends TitleAreaDialog { private void initialize() { if (fEntry != null) { - fBackendPathText.setText(fEntry.getBackendPath().toOSString()); + fBackendPathText.setText(fEntry.getBackendPathStr()); fLocalPathText.setText(fEntry.getLocalPath().toOSString()); } } @@ -227,8 +227,8 @@ public class PathMappingDialog extends TitleAreaDialog { return true; } - protected IPath getBackendPath() { - return new Path(fBackendPathText.getText().trim()); + protected String getBackendPathStr() { + return fBackendPathText.getText().trim(); } protected IPath getLocalPath() { @@ -241,7 +241,7 @@ public class PathMappingDialog extends TitleAreaDialog { fEntry = new MapEntrySourceContainer(); fMapping.addMapEntry(fEntry); } - fEntry.setBackendPath(getBackendPath()); + fEntry.setBackendPathStr(getBackendPathStr()); fEntry.setLocalPath(getLocalPath()); super.okPressed(); } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.tests/src/org/eclipse/cdt/dsf/gdb/tests/AllTests.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.tests/src/org/eclipse/cdt/dsf/gdb/tests/AllTests.java index 527ded83908..451dd8eaece 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.tests/src/org/eclipse/cdt/dsf/gdb/tests/AllTests.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.tests/src/org/eclipse/cdt/dsf/gdb/tests/AllTests.java @@ -27,6 +27,7 @@ import org.junit.runners.Suite.SuiteClasses; LaunchUtilsTest.class, MIStringHandlerTests.class, ProcStatParserTest.class, + FilePartsTest.class, }) public class AllTests { // Often overriding BeforeClass method here diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.tests/src/org/eclipse/cdt/dsf/gdb/tests/FilePartsTest.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.tests/src/org/eclipse/cdt/dsf/gdb/tests/FilePartsTest.java new file mode 100644 index 00000000000..fe17cc021fc --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.tests/src/org/eclipse/cdt/dsf/gdb/tests/FilePartsTest.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright (c) 2016 Kichwa Coders AB 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: + * Jonah Graham (Kichwa Coders) - Initial Implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.gdb.tests; + +import static org.junit.Assert.assertEquals; + +import org.eclipse.cdt.debug.core.CDebugUtils; +import org.junit.Test; + +/** + * TODO: Move this test closer to the code it is testing. + * + * At the time I wrote this test, there was no obvious place to put it, a test + * suite for org.eclipse.cdt.debug.core is needed. + * + */ +public class FilePartsTest { + @Test + public void testFileParts() { + assertEquals("", CDebugUtils.getFileParts("").getFolder()); + assertEquals("", CDebugUtils.getFileParts("").getFileName()); + assertEquals("", CDebugUtils.getFileParts("").getExtension()); + + assertEquals("", CDebugUtils.getFileParts(".").getFolder()); + assertEquals(".", CDebugUtils.getFileParts(".").getFileName()); + assertEquals("", CDebugUtils.getFileParts(".").getExtension()); + + assertEquals("", CDebugUtils.getFileParts(".d").getFolder()); + assertEquals(".d", CDebugUtils.getFileParts(".d").getFileName()); + assertEquals("d", CDebugUtils.getFileParts(".d").getExtension()); + + assertEquals("", CDebugUtils.getFileParts(".dot").getFolder()); + assertEquals(".dot", CDebugUtils.getFileParts(".dot").getFileName()); + assertEquals("dot", CDebugUtils.getFileParts(".dot").getExtension()); + + assertEquals("", CDebugUtils.getFileParts("file").getFolder()); + assertEquals("file", CDebugUtils.getFileParts("file").getFileName()); + assertEquals("", CDebugUtils.getFileParts("file").getExtension()); + + assertEquals("", CDebugUtils.getFileParts("file.").getFolder()); + assertEquals("file.", CDebugUtils.getFileParts("file.").getFileName()); + assertEquals("", CDebugUtils.getFileParts("file.").getExtension()); + + assertEquals("", CDebugUtils.getFileParts("file.d").getFolder()); + assertEquals("file.d", CDebugUtils.getFileParts("file.d").getFileName()); + assertEquals("d", CDebugUtils.getFileParts("file.d").getExtension()); + + assertEquals("", CDebugUtils.getFileParts("file.dot").getFolder()); + assertEquals("file.dot", CDebugUtils.getFileParts("file.dot").getFileName()); + assertEquals("dot", CDebugUtils.getFileParts("file.dot").getExtension()); + + assertEquals("/folder/", CDebugUtils.getFileParts("/folder/file.dot").getFolder()); + assertEquals("file.dot", CDebugUtils.getFileParts("/folder/file.dot").getFileName()); + assertEquals("dot", CDebugUtils.getFileParts("/folder/file.dot").getExtension()); + + assertEquals("/folder1/folder2/folder3/", CDebugUtils.getFileParts("/folder1/folder2/folder3/file.dot").getFolder()); + assertEquals("file.dot", CDebugUtils.getFileParts("/folder/file.dot").getFileName()); + assertEquals("dot", CDebugUtils.getFileParts("/folder/file.dot").getExtension()); + + assertEquals("/folder/", CDebugUtils.getFileParts("/folder/.dot").getFolder()); + assertEquals(".dot", CDebugUtils.getFileParts("/folder/.dot").getFileName()); + assertEquals("dot", CDebugUtils.getFileParts("/folder/.dot").getExtension()); + + assertEquals("/folder/../other/", CDebugUtils.getFileParts("/folder/../other/.dot").getFolder()); + assertEquals(".dot", CDebugUtils.getFileParts("/folder/../other/.dot").getFileName()); + assertEquals("dot", CDebugUtils.getFileParts("/folder/../other/.dot").getExtension()); + + assertEquals("/folder//", CDebugUtils.getFileParts("/folder//.dot").getFolder()); + assertEquals(".dot", CDebugUtils.getFileParts("/folder//.dot").getFileName()); + assertEquals("dot", CDebugUtils.getFileParts("/folder//.dot").getExtension()); + + assertEquals("C:\\folder\\", CDebugUtils.getFileParts("C:\\folder\\.dot").getFolder()); + assertEquals(".dot", CDebugUtils.getFileParts("C:\\folder\\.dot").getFileName()); + assertEquals("dot", CDebugUtils.getFileParts("C:\\folder\\.dot").getExtension()); + + assertEquals("C:\\\\folder\\", CDebugUtils.getFileParts("C:\\\\folder\\.dot").getFolder()); + assertEquals(".dot", CDebugUtils.getFileParts("C:\\\\folder\\.dot").getFileName()); + assertEquals("dot", CDebugUtils.getFileParts("C:\\\\folder\\.dot").getExtension()); + + assertEquals("/folder1/folder2/folder3/", CDebugUtils.getFileParts("/folder1/folder2/folder3/").getFolder()); + assertEquals("", CDebugUtils.getFileParts("/folder1/folder2/folder3/").getFileName()); + assertEquals("", CDebugUtils.getFileParts("/folder1/folder2/folder3/").getExtension()); + + assertEquals("/", CDebugUtils.getFileParts("/").getFolder()); + assertEquals("", CDebugUtils.getFileParts("/").getFileName()); + assertEquals("", CDebugUtils.getFileParts("/").getExtension()); + + assertEquals("\\\\unc\\path\\", CDebugUtils.getFileParts("\\\\unc\\path\\file.dot").getFolder()); + assertEquals("file.dot", CDebugUtils.getFileParts("\\\\unc\\path\\file.dot").getFileName()); + assertEquals("dot", CDebugUtils.getFileParts("\\\\unc\\path\\file.dot").getExtension()); + + } +} diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbSourceLookupDirector.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbSourceLookupDirector.java index 4a4bad1d064..b52a4d78a19 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbSourceLookupDirector.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/launching/GdbSourceLookupDirector.java @@ -70,10 +70,10 @@ public class GdbSourceLookupDirector extends DsfSourceLookupDirector { if (container instanceof MapEntrySourceContainer) { MapEntrySourceContainer sourceSubContainer = (MapEntrySourceContainer) container; - IPath from = sourceSubContainer.getBackendPath(); + String from = sourceSubContainer.getBackendPathStr(); IPath to = sourceSubContainer.getLocalPath(); if (from != null && to != null) { - entries.put(from.toOSString(), to.toOSString()); + entries.put(from, to.toOSString()); } } else if (container.isComposite()) { ISourceContainer[] childContainers; diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/SourceLookupTest.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/SourceLookupTest.java index 195150862d1..e191ce0561b 100644 --- a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/SourceLookupTest.java +++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/SourceLookupTest.java @@ -170,12 +170,12 @@ public class SourceLookupTest extends BaseParametrizedTestCase { /** * Map entry for non-canonical build dirs */ - protected MapEntrySourceContainer fMapEntrySourceContainerN = new MapEntrySourceContainer( - new Path(BUILD_NONCANONICAL_PATH), new Path(SOURCE_ABSPATH)); + protected MapEntrySourceContainer fMapEntrySourceContainerN = new MapEntrySourceContainer(BUILD_NONCANONICAL_PATH, + new Path(SOURCE_ABSPATH)); /** * Map entry for canonical build dirs */ - protected MapEntrySourceContainer fMapEntrySourceContainerC = new MapEntrySourceContainer(new Path(BUILD_ABSPATH), + protected MapEntrySourceContainer fMapEntrySourceContainerC = new MapEntrySourceContainer(BUILD_ABSPATH, new Path(SOURCE_ABSPATH)); protected AsyncCompletionWaitor fBreakpointInstalledWait = new AsyncCompletionWaitor(); @@ -493,8 +493,13 @@ public class SourceLookupTest extends BaseParametrizedTestCase { * Non-canonical build path */ @Test - @Ignore("Not supported because GDB does not handle non-canonical paths. See Bug 477057") public void sourceSubstituteAN() throws Throwable { + /* + * GDB < 6.8 does not work correctly with substitute-paths with .. in the + * build path when the build path is an absolute path. GDB 6.8 and above + * works fine in this case. + */ + assumeGdbVersionAtLeast("6.8"); sourceMapping(EXEC_AN_NAME, true); } @@ -532,8 +537,13 @@ public class SourceLookupTest extends BaseParametrizedTestCase { * Non-canonical build path */ @Test - @Ignore("Not supported because GDB does not handle non-canonical paths. See Bug 477057") public void sourceSubstituteRN() throws Throwable { + /* + * GDB < 7.6 does not work correctly with substitute-paths with .. in the + * build path when the build path is a relative path. GDB 7.6 and above + * works fine in this case. + */ + assumeGdbVersionAtLeast("7.6"); sourceMapping(EXEC_RN_NAME, true); } @@ -571,8 +581,13 @@ public class SourceLookupTest extends BaseParametrizedTestCase { * Non-canonical build path */ @Test - @Ignore("Not supported because GDB does not handle non-canonical paths. See Bug 477057") public void sourceSubstituteBreakpointsAN() throws Throwable { + /* + * GDB < 6.8 does not work correctly with substitute-paths with .. in the + * build path when the build path is an absolute path. GDB 6.8 and above + * works fine in this case. + */ + assumeGdbVersionAtLeast("6.8"); sourceMappingBreakpoints(EXEC_AN_NAME, true); } @@ -610,8 +625,13 @@ public class SourceLookupTest extends BaseParametrizedTestCase { * Non-canonical build path */ @Test - @Ignore("Not supported because GDB does not handle non-canonical paths. See Bug 477057") public void sourceSubstituteBreakpointsRN() throws Throwable { + /* + * GDB < 7.6 does not work correctly with substitute-paths with .. in the + * build path when the build path is a relative path. GDB 7.6 and above + * works fine in this case. + */ + assumeGdbVersionAtLeast("7.6"); sourceMappingBreakpoints(EXEC_RN_NAME, true); } @@ -640,8 +660,8 @@ public class SourceLookupTest extends BaseParametrizedTestCase { doMappingAndLaunch(EXEC_AC_NAME, withBackend); DsfSourceLookupDirector sourceLocator = (DsfSourceLookupDirector) getGDBLaunch().getSourceLocator(); - MapEntrySourceContainer incorrectMapEntry = new MapEntrySourceContainer( - new Path(BUILD_ABSPATH + "/incorrectsubpath"), new Path(SOURCE_ABSPATH)); + MapEntrySourceContainer incorrectMapEntry = new MapEntrySourceContainer(BUILD_ABSPATH + "/incorrectsubpath", + new Path(SOURCE_ABSPATH)); if (withBackend) { assertSourceFound(); @@ -976,8 +996,7 @@ public class SourceLookupTest extends BaseParametrizedTestCase { * substitution, we want to make sure that we process the other * MappingSourceContainer correctly */ - substituteContainer - .addMapEntry(new MapEntrySourceContainer(new Path("/from_invalid"), new Path("/to_invalid"))); + substituteContainer.addMapEntry(new MapEntrySourceContainer("/from_invalid", new Path("/to_invalid"))); AbstractSourceLookupDirector director = setSourceContainer(substituteContainer); // this is the mapping we want to do the work @@ -1022,7 +1041,7 @@ public class SourceLookupTest extends BaseParametrizedTestCase { MappingSourceContainer mapContainer = new MappingSourceContainer("Mappings"); mapContainer.setIsMappingWithBackendEnabled(false); mapContainer - .addMapEntry(new MapEntrySourceContainer(new Path("/from_invalid"), new Path(SOURCE_ABSPATH))); + .addMapEntry(new MapEntrySourceContainer("/from_invalid", new Path(SOURCE_ABSPATH))); addSourceContainer(director, mapContainer); doLaunch(EXEC_PATH + EXEC_AC_NAME);