From 4e7d74a6be8b1cb417b2b6910b162b159d6aca1b Mon Sep 17 00:00:00 2001 From: John Cortell Date: Thu, 14 Apr 2011 20:41:44 +0000 Subject: [PATCH] Bug 341168 - EDC Dwarf Reader shouldn't do source mapping --- .../org/eclipse/cdt/internal/core/Util.java | 38 +++++++++++++++++++ .../debug/core/executables/Executable.java | 37 ++++++++++-------- .../views/executables/SourceFilesViewer.java | 29 +++++++++++--- 3 files changed, 84 insertions(+), 20 deletions(-) diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/Util.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/Util.java index b608e4061f4..6445ba72cb6 100644 --- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/Util.java +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/Util.java @@ -23,6 +23,7 @@ import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; public class Util { @@ -290,6 +291,43 @@ public class Util { } return new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, 0, msg, t); } + + /** + * Determines if [filename] is an absolute path specification on the host OS. For example, "c:\some\file" + * will return true on Windows, but false on UNIX. Conversely, "/some/file" will return false on Windows, + * true on Linux. "somefile.txt", "some/file", "./some/file", and "../some/file" will all return false on + * all hosts. + * + *

+ * UNC paths ("\\some\dir") are recognized as native on Windows. + * + * @param filename + * a file specification. Slashes do not need to be in native format or consistent, except for a + * UNC path, where both prefix slashes must be either forward or backwards. + */ + public static boolean isNativeAbsolutePath(String filename) { + if (Platform.getOS().equals(Platform.OS_WIN32)) { + if (filename.length() > 2) { + // "c:\some\dir" + if (filename.charAt(1) == ':') { + return filename.length() > 3 && isSlash(filename.charAt(2)); + } + else { + return filename.startsWith("\\\\") || // UNC //$NON-NLS-1$ + filename.startsWith("//"); // UNC converted to forward slashes //$NON-NLS-1$ + } + } + return false; + } + else { + // So much simpler on Linux/UNIX (and MacOS now?) + return filename.length() > 1 && isSlash(filename.charAt(0)); + } + } + + private static boolean isSlash(Character c) { + return c == '\\' || c == '/'; + } } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/Executable.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/Executable.java index 2cb2b47fdf9..ca7764a027e 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/Executable.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/Executable.java @@ -23,6 +23,7 @@ import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.debug.internal.core.Trace; +import org.eclipse.cdt.internal.core.Util; import org.eclipse.cdt.internal.core.model.CModelManager; import org.eclipse.cdt.internal.core.model.ExternalTranslationUnit; import org.eclipse.cdt.internal.core.model.TranslationUnit; @@ -214,22 +215,28 @@ public class Executable extends PlatformObject { // case than the actual file system path. Even if the file // system is not case sensitive this will confuse the Path // class. So make sure the path is canonical, otherwise - // breakpoints won't be resolved, etc.. Also check for relative - // path names and attempt to resolve them relative to the - // executable. - + // breakpoints won't be resolved, etc. Make sure to do this only + // for files that are specified as an absolute path at this + // point. Paths that are not absolute can't be trusted to + // java.io.File to canonicalize since that class will + // arbitrarily give the specification a local context, and we + // don't want that. A source file that continues to be + // non-absolute after having been run through source lookups + // (done in remapSourceFile() above) is effectively ambiguous + // and we should leave it that way. Users will need to configure + // a source lookup to give the file a local context if in fact + // the file is available on his machine. boolean fileExists = false; - - try { - File file = new File(filename); - fileExists = file.exists(); - if (fileExists) { - filename = file.getCanonicalPath(); - } else if (filename.startsWith(".")) { //$NON-NLS-1$ - file = new File(executablePath.removeLastSegments(1).toOSString(), filename); - filename = file.getCanonicalPath(); + boolean isNativeAbsPath = Util.isNativeAbsolutePath(filename); + if (isNativeAbsPath) { + try { + File file = new File(filename); + fileExists = file.exists(); + if (fileExists) { + filename = file.getCanonicalPath(); + } + } catch (IOException e) { // Do nothing. } - } catch (IOException e) { // Do nothing. } IFile wkspFile = null; @@ -266,7 +273,7 @@ public class Executable extends PlatformObject { // Be careful not to convert a unix path like // "/src/home" to "c:\source\home" on Windows. See // bugzilla 297781 - URI uri = (sourcePath.toFile().exists()) ? URIUtil.toURI(sourcePath) : URIUtil.toURI(filename, true); + URI uri = (isNativeAbsPath && sourcePath.toFile().exists()) ? URIUtil.toURI(sourcePath) : URIUtil.toURI(filename, true); tu = new ExternalTranslationUnit(cproject, uri, id); } diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesViewer.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesViewer.java index 640ba1291f2..0d7cb4ae76f 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesViewer.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesViewer.java @@ -21,6 +21,7 @@ import org.eclipse.cdt.debug.core.executables.ExecutablesManager; import org.eclipse.cdt.debug.core.executables.IExecutablesChangeListener; import org.eclipse.cdt.debug.internal.ui.sourcelookup.CSourceNotFoundEditorInput; import org.eclipse.cdt.debug.ui.ICDebugUIConstants; +import org.eclipse.cdt.internal.core.Util; import org.eclipse.cdt.internal.core.util.LRUCache; import org.eclipse.cdt.internal.ui.util.EditorUtility; import org.eclipse.cdt.ui.CUIPlugin; @@ -254,13 +255,31 @@ public class SourceFilesViewer extends BaseViewer { info.location = tu.getLocation(); if (info.location != null) { - File file = info.location.toFile(); - info.exists = file.exists(); - info.fileLength = file.length(); - info.lastModified = file.lastModified(); + // A source file with a non-absolute path has no local context; + // its location is ambiguous. Converting the IPath to a + // java.io.File would be wrong since that class makes arbitrary + // assumptions about where the file should be locally. See + // similar comment in Executable.getSourceFiles() + if (Util.isNativeAbsolutePath(info.location.toOSString()) ) { + File file = info.location.toFile(); + info.exists = file.exists(); + if (info.exists) { + info.fileLength = file.length(); + info.lastModified = file.lastModified(); + } + else { + info.fileLength = 0; + info.lastModified = 0; + } + } + else { + info.exists = false; + info.fileLength = 0; + info.lastModified = 0; + } info.originalLocation = new Path(executable.getOriginalLocation(tu)); - info.originalExists = info.originalLocation.toFile().exists(); + info.originalExists = Util.isNativeAbsolutePath(info.originalLocation.toOSString()) && info.originalLocation.toFile().exists(); } else { info.exists = false; info.fileLength = 0;