diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Binary.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Binary.java index 80e63c1d9d7..d8ff2809ff9 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Binary.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Binary.java @@ -308,9 +308,6 @@ public class Binary extends Openable implements IBinary { String[] sourceFiles = symbolreader.getSourceFiles(); if (sourceFiles != null && sourceFiles.length > 0) { for (String filename : sourceFiles) { - if (filename.startsWith(".")) { //$NON-NLS-1$ - filename = obj.getPath().removeLastSegments(1).append(filename).toOSString(); - } File file = new File(filename); try { if (file.exists()) { diff --git a/debug/org.eclipse.cdt.debug.core/plugin.properties b/debug/org.eclipse.cdt.debug.core/plugin.properties index e71bd234fc0..3a04b93ab66 100644 --- a/debug/org.eclipse.cdt.debug.core/plugin.properties +++ b/debug/org.eclipse.cdt.debug.core/plugin.properties @@ -43,3 +43,5 @@ containerName.directory=File System Directory containerDescription.directory=A directory in the local file system. containerName.absolutePath=Absolute File Path containerDescription.absolutePath=An absolute path to a file in the local file system. +containerName.programRelativePath=Program Relative File Path +containerDescription.programRelativePath=Program relative path to a file in the local file system. diff --git a/debug/org.eclipse.cdt.debug.core/plugin.xml b/debug/org.eclipse.cdt.debug.core/plugin.xml index 0745c828ead..90fbe9cafae 100644 --- a/debug/org.eclipse.cdt.debug.core/plugin.xml +++ b/debug/org.eclipse.cdt.debug.core/plugin.xml @@ -297,6 +297,12 @@ description="%containerDescription.absolutePath" id="org.eclipse.cdt.debug.core.containerType.absolutePath" name="%containerName.absolutePath"/> + + + org.eclipse.cdt.debug.core.containerType.programRelativePath). + */ + public static final String TYPE_ID = CDebugCorePlugin.getUniqueIdentifier() + ".containerType.programRelativePath"; //$NON-NLS-1$ + + /** + * The program's path. + */ + private IPath fProgramPath = Path.EMPTY; + + /** + * Default constructor. + */ + public ProgramRelativePathSourceContainer() { + } + + /** + * Special constructor used when trying to locate a source file without a + * launch or launch configuration context, but when a Binary context is + * available. Normally, this class is instantiated with the default (no arg) + * constructor and such instances are added to the source locator of a + * launch configuration. In those cases, we can obtain the the program + * (executable) context from the launch configuration. But in cases were CDT + * needs to search for a source file and there is no + * launch/launch-configuration context, it can explicitly create an instance + * using this constructor and call our {@link #findSourceElements(String)} + * method. + * + * @param program + * the executable context. Calling this with null is equivalent + * to calling the default constructor. + */ + public ProgramRelativePathSourceContainer(IBinary program) { + if (program != null) { + fProgramPath = program.getPath(); + } + } + + /** + * If [sourceName] is a relative path, and applying it to the location of + * the program (executable) produces an absolute path that points to an + * actual file, then we return a LocalFileStorage for that file. Otherwise + * we return an empty array. We always return at most one element. + * + * @see org.eclipse.debug.core.sourcelookup.ISourceContainer#findSourceElements(java.lang.String) + */ + public Object[] findSourceElements( String sourceName ) throws CoreException { + + if (sourceName == null){ + return new Object[0]; + } + + // check if source path is a relative path + IPath sourcePath = new Path(sourceName); + if (sourcePath.isAbsolute()){ + return new Object[0]; + } + + // get program (executable) absolute path + IPath programPath = getProgramLocation(); + if (programPath == Path.EMPTY){ + return new Object[0]; + } + + // remove the name of the program from the program path + programPath = programPath.removeLastSegments(1); + // append the relative source path to the absolute location of the program + sourcePath = programPath.append(sourcePath); + + // check if source file exists and is valid + File sourceFile = sourcePath.toFile(); + if ( sourceFile.exists() && sourceFile.isFile() ) { + return new Object[] { new LocalFileStorage( sourceFile ) }; + } + + return new Object[0]; + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.sourcelookup.ISourceContainer#getName() + */ + public String getName() { + return SourceLookupMessages.getString("ProgramRelativePathSourceContainer.0"); //$NON-NLS-1$ + } + + /* (non-Javadoc) + * @see org.eclipse.debug.core.sourcelookup.ISourceContainer#getType() + */ + public ISourceContainerType getType() { + return getSourceContainerType( TYPE_ID ); + } + + private synchronized IPath getProgramLocation() throws CoreException { + + // compute fProgramPath only if doesn't exist already + if (fProgramPath.isEmpty()){ + // get launch configuration + ISourceLookupDirector director = getDirector(); + if (director == null) { + return fProgramPath; // return empty path + } + ILaunchConfiguration configuration = director.getLaunchConfiguration(); + if (configuration == null) { + return fProgramPath; // return empty path + } + + // get current project + String projectName = configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String)null); + ICProject project = CoreModel.getDefault().getCModel().getCProject(projectName); + if (project == null || !project.exists()) { + return fProgramPath; // return empty path + } + + // get program name + String programName = configuration.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, (String)null); + if (programName == null){ + return fProgramPath; // return empty path + } + + // get executable file + IFile exeFile = null; + try { + exeFile = project.getProject().getFile(new Path(programName)); + } + catch (IllegalArgumentException e){ + return fProgramPath; // return empty path + } + + if (!exeFile.exists()){ + return fProgramPath; // return empty path + } + + // get program absolute path + fProgramPath = exeFile.getLocation(); + } + + // return program absolute path + return fProgramPath; + } +} diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/sourcelookup/SourceLookupMessages.properties b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/sourcelookup/SourceLookupMessages.properties index a8981272368..60edcdc9725 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/sourcelookup/SourceLookupMessages.properties +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/sourcelookup/SourceLookupMessages.properties @@ -11,3 +11,4 @@ ############################################################################### MappingSourceContainer.0=Source lookup error AbsolutePathSourceContainer.0=Absolute File Path +ProgramRelativePathSourceContainer.0=Program Relative File Path diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/CSourceLookupDirector.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/CSourceLookupDirector.java index a6301be0609..72eee12d704 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/CSourceLookupDirector.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/CSourceLookupDirector.java @@ -19,6 +19,7 @@ import java.util.Set; import org.eclipse.cdt.debug.core.CDebugCorePlugin; import org.eclipse.cdt.debug.core.model.ICBreakpoint; import org.eclipse.cdt.debug.core.sourcelookup.AbsolutePathSourceContainer; +import org.eclipse.cdt.debug.core.sourcelookup.ProgramRelativePathSourceContainer; import org.eclipse.cdt.debug.core.sourcelookup.MappingSourceContainer; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; @@ -152,6 +153,14 @@ public class CSourceLookupDirector extends AbstractSourceLookupDirector { if ( container instanceof AbsolutePathSourceContainer ) { return ( ((AbsolutePathSourceContainer)container).isValidAbsoluteFilePath( sourceName ) ); } + if ( container instanceof ProgramRelativePathSourceContainer ) { + try { + Object[] elements = ((ProgramRelativePathSourceContainer)container).findSourceElements(sourceName); + return elements.length > 0; + } catch (CoreException e) { + return false; + } + } try { ISourceContainer[] containers; containers = container.getSourceContainers(); diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/CSourcePathComputerDelegate.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/CSourcePathComputerDelegate.java index 479bce4cd04..2af9e1d6abf 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/CSourcePathComputerDelegate.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/CSourcePathComputerDelegate.java @@ -17,6 +17,7 @@ import java.util.List; import org.eclipse.cdt.debug.core.CDebugCorePlugin; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.cdt.debug.core.sourcelookup.AbsolutePathSourceContainer; +import org.eclipse.cdt.debug.core.sourcelookup.ProgramRelativePathSourceContainer; import org.eclipse.cdt.debug.core.sourcelookup.MappingSourceContainer; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; @@ -43,9 +44,27 @@ public class CSourcePathComputerDelegate implements ISourcePathComputerDelegate * @see org.eclipse.debug.core.sourcelookup.ISourcePathComputerDelegate#computeSourceContainers(org.eclipse.debug.core.ILaunchConfiguration, org.eclipse.core.runtime.IProgressMonitor) */ public ISourceContainer[] computeSourceContainers( ILaunchConfiguration configuration, IProgressMonitor monitor ) throws CoreException { - // First, get all the the containers in the global preferences + // First, get all the the containers in the global preferences (but add them last) ISourceContainer[] common = CDebugCorePlugin.getDefault().getCommonSourceLookupDirector().getSourceContainers(); - List containers = new ArrayList( common.length + 1 ); + + List containers = new ArrayList( common.length + 2 ); + + // Add a container that fetches files that are specified with an absolute path + containers.add(new AbsolutePathSourceContainer() ); + + // Add a container that fetches files that are specified with a program relative path + containers.add(new ProgramRelativePathSourceContainer()); + + // Add a container that looks in the project specified in the configuration + String projectName = configuration.getAttribute( ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String)null ); + if (projectName != null && projectName.length() > 0) { + IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject( projectName ); + if ( project.exists() ) { + containers.add(new ProjectSourceContainer( project, true ) ); + } + } + + // Finally, add the common (global) containers for ( ISourceContainer sc : common ) { // If the container is a path-mapper, use a copy (why?) if ( sc.getType().getId().equals( MappingSourceContainer.TYPE_ID ) ) @@ -53,18 +72,6 @@ public class CSourcePathComputerDelegate implements ISourcePathComputerDelegate containers.add( sc ); } - // Add a container that looks in the project specified in the configuration - String projectName = configuration.getAttribute( ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String)null ); - if (projectName != null && projectName.length() > 0) { - IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject( projectName ); - if ( project.exists() ) { - containers.add( 0, new ProjectSourceContainer( project, true ) ); - } - } - - // Add a container that fetches files that are specified with an absolute path - containers.add( 0, new AbsolutePathSourceContainer() ); - return containers.toArray( new ISourceContainer[containers.size()] ); } } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/InternalSourceLookupMessages.properties b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/InternalSourceLookupMessages.properties index 22636cfaf99..930363f1409 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/InternalSourceLookupMessages.properties +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/InternalSourceLookupMessages.properties @@ -31,3 +31,4 @@ MappingSourceContainerType.0=Source lookup: unable to restore map entry - expect MappingSourceContainerType.1=Source lookup: unable to restore mapping - expecting mapping element. MappingSourceContainerType.2=Source lookup: unable to restore mapping - invalid memento. SourceUtils.0=Mapping +ProgramRelativePathSourceContainerType.1=Source lookup: unable to restore program relative source container - invalid memento. diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/ProgramRelativePathSourceContainerType.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/ProgramRelativePathSourceContainerType.java new file mode 100644 index 00000000000..e8869e31ec2 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/ProgramRelativePathSourceContainerType.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2008 Freescale 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: + * Freescale - Initial implementation + *******************************************************************************/ + +package org.eclipse.cdt.debug.internal.core.sourcelookup; + +import org.eclipse.cdt.debug.core.sourcelookup.ProgramRelativePathSourceContainer; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.sourcelookup.ISourceContainer; +import org.eclipse.debug.core.sourcelookup.containers.AbstractSourceContainerTypeDelegate; + +public class ProgramRelativePathSourceContainerType extends AbstractSourceContainerTypeDelegate { + + private final static String ELEMENT_NAME = "programRelativePath"; //$NON-NLS-1$ + + public ISourceContainer createSourceContainer(String memento) throws CoreException { + if ( ELEMENT_NAME.equals( memento ) ) { + return new ProgramRelativePathSourceContainer(); + } + abort( InternalSourceLookupMessages.getString("ProgramRelativePathSourceContainerType.1"), null ); //$NON-NLS-1$ + return null; + } + + public String getMemento(ISourceContainer container) throws CoreException { + if (container instanceof ProgramRelativePathSourceContainer){ + return ELEMENT_NAME; + } + else{ + return ""; //$NON-NLS-1$ + } + } +} diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/srcfinder/CSourceFinder.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/srcfinder/CSourceFinder.java index e57805c716b..43b10b94489 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/srcfinder/CSourceFinder.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/srcfinder/CSourceFinder.java @@ -21,6 +21,7 @@ import org.eclipse.cdt.core.ISourceFinder; import org.eclipse.cdt.core.model.IBinary; import org.eclipse.cdt.debug.core.CDebugCorePlugin; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.cdt.debug.core.sourcelookup.ProgramRelativePathSourceContainer; import org.eclipse.cdt.debug.internal.core.sourcelookup.CSourceLookupDirector; import org.eclipse.cdt.internal.core.model.ExternalTranslationUnit; import org.eclipse.core.filesystem.URIUtil; @@ -73,6 +74,14 @@ public class CSourceFinder implements ISourceFinder, ILaunchConfigurationListene */ private Map fConfigLocators = Collections.synchronizedMap(new HashMap()); + /** + * We use this when we don't have an ILaunch or ILaunchConfiguration + * locator. A program relative container instance is automatically added to + * every CDT launch configuration. So when we lack a configuration context, + * we rely on this container to help us resolve relative paths. + */ + private ProgramRelativePathSourceContainer fRelativePathContainer; + /** * Constructor. * @@ -84,6 +93,8 @@ public class CSourceFinder implements ISourceFinder, ILaunchConfigurationListene assert(binary != null); fBinary = binary; + fRelativePathContainer = new ProgramRelativePathSourceContainer(binary); + ILaunchManager lmgr = DebugPlugin.getDefault().getLaunchManager(); lmgr.addLaunchConfigurationListener(this); lmgr.addLaunchListener(this); @@ -145,6 +156,16 @@ public class CSourceFinder implements ISourceFinder, ILaunchConfigurationListene if (fLaunchLocator != null) { foundElement = fLaunchLocator.getSourceElement(compilationPath); } + else { + // If there isn't a launch/config locator, we need to explicitly + // try to resolve relative paths...relative to the binary + // location. + Object[] elements = fRelativePathContainer.findSourceElements(compilationPath); + if (elements.length > 0) { + assert elements.length == 1; // relative path container should return at most one element + foundElement = elements[0]; + } + } // If not found, look in the global (common) locator if (foundElement == null) { diff --git a/debug/org.eclipse.cdt.debug.ui/icons/obj16/program_rel_path_obj.gif b/debug/org.eclipse.cdt.debug.ui/icons/obj16/program_rel_path_obj.gif new file mode 100644 index 00000000000..7e464af9d1c Binary files /dev/null and b/debug/org.eclipse.cdt.debug.ui/icons/obj16/program_rel_path_obj.gif differ diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.xml b/debug/org.eclipse.cdt.debug.ui/plugin.xml index ec258095b59..210fb5dda17 100644 --- a/debug/org.eclipse.cdt.debug.ui/plugin.xml +++ b/debug/org.eclipse.cdt.debug.ui/plugin.xml @@ -1647,6 +1647,10 @@ containerTypeID="org.eclipse.cdt.debug.core.containerType.absolutePath" icon="icons/obj16/abspath_obj.gif" id="org.eclipse.cdt.debug.ui.sourceContainerPresentation.absolutePath"/> +