cdt/cdt_5_0_x/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/Executable.java
/*******************************************************************************
* Copyright (c) 2008 Nokia 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:
* Nokia - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.debug.core.executables;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.cdt.core.CCorePlugin;
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.internal.core.model.CModelManager;
import org.eclipse.cdt.internal.core.model.ExternalTranslationUnit;
import org.eclipse.cdt.internal.core.model.TranslationUnit;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.content.IContentTypeManager;
public class Executable extends PlatformObject {
static public boolean isExecutableFile(IPath path) {
// ignore directories
if (path.toFile().isDirectory()) {
return false;
}
// Only if file has no extension, has an extension that is an integer
// or is a binary file content type
String ext = path.getFileExtension();
if (ext != null) {
// shared libraries often have a version number
boolean isNumber = true;
for (int i = 0; i < ext.length(); ++i)
if (!Character.isDigit(ext.charAt(i))) {
isNumber = false;
break;
}
if (!isNumber) {
boolean isBinary = false;
final IContentTypeManager ctm = Platform.getContentTypeManager();
final IContentType ctbin = ctm.getContentType(CCorePlugin.CONTENT_TYPE_BINARYFILE);
final IContentType[] cts = ctm.findContentTypesFor(path.toFile().getName());
for (int i = 0; !isBinary && i < cts.length; i++) {
isBinary = cts[i].isKindOf(ctbin);
}
if (!isBinary) {
return false;
}
}
}
return true;
}
@Override
public boolean equals(Object arg0) {
if (arg0 instanceof Executable)
{
Executable exe = (Executable)arg0;
return exe.getPath().equals(this.getPath());
}
return super.equals(arg0);
}
private IPath path;
private IProject project;
private String name;
private IResource resource;
private Map<ITranslationUnit, String> remappedPaths;
private ArrayList<ITranslationUnit> sourceFiles;
private boolean refreshSourceFiles;
public IPath getPath() {
return path;
}
public IProject getProject() {
return project;
}
public Executable(IPath path, IProject project, IResource resource) {
this.path = path;
this.project = project;
this.name = new File(path.toOSString()).getName();
this.resource = resource;
remappedPaths = new HashMap<ITranslationUnit, String>();
sourceFiles = new ArrayList<ITranslationUnit>();
refreshSourceFiles = true;
}
public IResource getResource() {
return resource;
}
@Override
public String toString() {
return path.toString();
}
public String getName() {
return name;
}
@SuppressWarnings("unchecked")
@Override
public Object getAdapter(Class adapter) {
if (adapter.equals(IResource.class))
if (getResource() != null)
return getResource();
else
return this.getProject();
return super.getAdapter(adapter);
}
public synchronized TranslationUnit[] getSourceFiles(IProgressMonitor monitor) {
if (!refreshSourceFiles)
return sourceFiles.toArray(new TranslationUnit[sourceFiles.size()]) ;
// Try to get the list of source files used to build the binary from the
// symbol information.
remappedPaths.clear();
sourceFiles.clear();
CModelManager factory = CModelManager.getDefault();
ICProject cproject = factory.create(project);
String[] symReaderSources = ExecutablesManager.getExecutablesManager().getSourceFiles(this, monitor);
if (symReaderSources != null && symReaderSources.length > 0) {
for (int i = 0; i < symReaderSources.length; i++) {
String filename = symReaderSources[i];
String orgPath = filename;
filename = ExecutablesManager.getExecutablesManager().remapSourceFile(this, filename);
// Sometimes the path in the symbolics will have a
// different
// 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.
try {
File file = new File(filename);
if (file.exists()) {
filename = file.getCanonicalPath();
} else if (filename.startsWith(".")) { //$NON-NLS-1$
file = new File(path.removeLastSegments(1).toOSString(), filename);
filename = file.getCanonicalPath();
}
} catch (IOException e) { // Do nothing.
}
// See if this source file is already in the project.
// We check this to determine if we should create a
// TranslationUnit or ExternalTranslationUnit
IFile sourceFile = getProject().getFile(filename);
IPath path = new Path(filename);
IFile wkspFile = null;
if (sourceFile.exists())
wkspFile = sourceFile;
else {
IFile[] filesInWP = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(path);
for (int j = 0; j < filesInWP.length; j++) {
if (filesInWP[j].isAccessible()) {
wkspFile = filesInWP[j];
break;
}
}
}
// Create a translation unit for this file and add it as
// a child of the binary
String id = CoreModel.getRegistedContentTypeId(sourceFile.getProject(), sourceFile.getName());
if (id != null) { // Don't add files we can't get an
// ID for.
TranslationUnit tu;
if (wkspFile != null)
tu = new TranslationUnit(cproject, wkspFile, id);
else
tu = new ExternalTranslationUnit(cproject, URIUtil.toURI(path), id);
sourceFiles.add(tu);
if (!orgPath.equals(filename)) {
remappedPaths.put(tu, orgPath);
}
}
}
}
refreshSourceFiles = false;
return sourceFiles.toArray(new TranslationUnit[sourceFiles.size()]) ;
}
public void setRefreshSourceFiles(boolean refreshSourceFiles) {
this.refreshSourceFiles = refreshSourceFiles;
}
public synchronized String getOriginalLocation(ITranslationUnit tu) {
String orgLocation = remappedPaths.get(tu);
if (orgLocation == null)
orgLocation = tu.getLocation().toOSString();
return orgLocation;
}
}