| /******************************************************************************* |
| * Copyright (c) 2004, 2011 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 |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * QNX Software Systems - Initial API and implementation |
| * Alex Collins (Broadcom Corp.) - choose build config automatically |
| * James Blackburn (Broadcom Corp.) |
| *******************************************************************************/ |
| package org.eclipse.cdt.launch; |
| |
| import java.io.IOException; |
| import java.util.HashSet; |
| import java.util.Set; |
| |
| import org.eclipse.cdt.core.CCorePlugin; |
| import org.eclipse.cdt.core.IBinaryParser; |
| import org.eclipse.cdt.core.IBinaryParser.IBinaryObject; |
| import org.eclipse.cdt.core.model.CoreModel; |
| import org.eclipse.cdt.core.model.CoreModelUtil; |
| import org.eclipse.cdt.core.settings.model.ICConfigExtensionReference; |
| import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; |
| import org.eclipse.cdt.core.settings.model.ICOutputEntry; |
| import org.eclipse.cdt.core.settings.model.ICProjectDescription; |
| import org.eclipse.cdt.core.settings.model.extension.CBuildData; |
| import org.eclipse.cdt.core.settings.model.extension.CConfigurationData; |
| import org.eclipse.cdt.core.settings.model.util.CDataUtil; |
| import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; |
| import org.eclipse.cdt.internal.core.resources.ResourceLookup; |
| import org.eclipse.cdt.utils.CommandLineUtil; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.SubProgressMonitor; |
| import org.eclipse.core.variables.IStringVariableManager; |
| import org.eclipse.core.variables.VariablesPlugin; |
| import org.eclipse.debug.core.ILaunchConfiguration; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.activities.IActivityManager; |
| import org.eclipse.ui.activities.IWorkbenchActivitySupport; |
| |
| /** |
| * Utility methods. |
| */ |
| public class LaunchUtils { |
| |
| /** |
| * A specialised WrapperProgressMonitor which doesn't let cancellation of the |
| * child build task cause cancellation of our top-level launch task. |
| */ |
| static class BuildProgressMonitor extends SubProgressMonitor { |
| private boolean cancelled; |
| |
| public BuildProgressMonitor(IProgressMonitor monitor, int ticks, int style) { |
| super(monitor, ticks, style); |
| } |
| |
| public BuildProgressMonitor(IProgressMonitor monitor, int ticks) { |
| this(monitor, ticks, 0); |
| } |
| |
| @Override |
| public void setCanceled(boolean b) { |
| // Only cancel this operation, not the top-level launch. |
| cancelled = b; |
| } |
| |
| @Override |
| public boolean isCanceled() { |
| // Canceled if this monitor has been explicitly canceled |
| // || parent has been canceled. |
| return cancelled || super.isCanceled(); |
| } |
| } |
| |
| /** |
| * For given launch configuration returns the program arguments as |
| * an array of individual arguments. |
| */ |
| public static String[] getProgramArgumentsArray(ILaunchConfiguration config) throws CoreException { |
| return parseArguments(getProgramArguments(config)); |
| } |
| |
| /** |
| * Returns the program arguments as a String. |
| */ |
| public static String getProgramArguments(ILaunchConfiguration config) throws CoreException { |
| String args = config.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, (String) null); |
| if (args != null) { |
| args = getStringVariableManager().performStringSubstitution(args); |
| } |
| return args; |
| } |
| |
| /** |
| * @since 6.0 |
| */ |
| public static IBinaryObject getBinary(IProject project, IPath exePath) throws CoreException { |
| ICConfigExtensionReference[] parserRef = CCorePlugin.getDefault().getDefaultBinaryParserExtensions(project); |
| for (int i = 0; i < parserRef.length; i++) { |
| try { |
| IBinaryParser parser = CoreModelUtil.getBinaryParser(parserRef[i]); |
| IBinaryObject exe = (IBinaryObject)parser.getBinary(exePath); |
| if (exe != null) { |
| return exe; |
| } |
| } catch (ClassCastException e) { |
| } catch (IOException e) { |
| } |
| } |
| IBinaryParser parser = CCorePlugin.getDefault().getDefaultBinaryParser(); |
| try { |
| IBinaryObject exe = (IBinaryObject)parser.getBinary(exePath); |
| return exe; |
| } catch (ClassCastException e) { |
| } catch (IOException e) { |
| } |
| return null; |
| } |
| |
| /** |
| * @since 6.0 |
| */ |
| public static IBinaryObject getBinary(String programName, String projectName) |
| throws CoreException |
| { |
| if (programName != null ) { |
| IPath exePath = new Path(programName); |
| IProject project = null; |
| if (projectName != null && !projectName.equals("")) { //$NON-NLS-1$ |
| project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); |
| if (project == null || project.getLocation() == null) |
| { |
| return null; |
| } |
| if (!exePath.isAbsolute()) { |
| exePath = project.getLocation().append(exePath); |
| } |
| } |
| return getBinary(project, exePath); |
| } |
| return null; |
| } |
| |
| |
| /** |
| * Convenience method. |
| */ |
| public static IStringVariableManager getStringVariableManager() { |
| return VariablesPlugin.getDefault().getStringVariableManager(); |
| } |
| |
| private static String[] parseArguments(String args) { |
| return CommandLineUtil.argumentsToArray(args); |
| } |
| |
| /** |
| * @since 6.1 |
| */ |
| @SuppressWarnings("unchecked") |
| public static void enableActivity(final String activityID, final boolean enableit) |
| { |
| if (PlatformUI.isWorkbenchRunning()) |
| { |
| PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { |
| @Override |
| public void run() { |
| IWorkbenchActivitySupport workbenchActivitySupport = PlatformUI.getWorkbench().getActivitySupport(); |
| IActivityManager activityManager = workbenchActivitySupport.getActivityManager(); |
| Set<String> enabledActivityIds = new HashSet<String>(activityManager.getEnabledActivityIds()); |
| boolean changed = false; |
| if (enableit) |
| changed = enabledActivityIds.add(activityID); |
| else |
| changed = enabledActivityIds.remove(activityID); |
| if (changed) |
| workbenchActivitySupport.setEnabledActivityIds(enabledActivityIds); |
| } |
| }); |
| } |
| } |
| |
| /** |
| * Get the build configuration that most likely builds the given program path. |
| * The build configuration is chosen as the one that outputs to a directory that contains |
| * the given program. |
| * |
| * @param projectDesc The description for the project in which to search for the configuration. |
| * @param programPath The path to the program to search the build configurations for |
| * @return The build configuration that builds programName; or null if none or more than one were found. |
| * @since 7.0 |
| */ |
| public static ICConfigurationDescription getBuildConfigByProgramPath(IProject project, String programPath) { |
| if (project == null || programPath == null) |
| return null; |
| ICProjectDescription projectDesc = CoreModel.getDefault().getProjectDescription(project, false); |
| if (projectDesc == null) |
| return null; |
| |
| // If the program path is relative, it must be relative to the projects root |
| IPath path = new Path(programPath); |
| if (!path.isAbsolute()) { |
| IPath projLocation = project.getLocation(); |
| if (projLocation == null) |
| return null; |
| path = projLocation.append(path); |
| } |
| |
| // Get all possible files that the program path could refer to |
| IFile[] files = ResourceLookup.findFilesForLocation(path); |
| |
| // Find the build config whose output directory matches one of the possible files |
| ICConfigurationDescription buildConfig = null; |
| findCfg: for (ICConfigurationDescription cfgDes : projectDesc.getConfigurations()) { |
| CConfigurationData cfgData = cfgDes.getConfigurationData(); |
| if (cfgData == null) |
| continue; |
| CBuildData buildData = cfgData.getBuildData(); |
| if (buildData == null) |
| continue; |
| for (ICOutputEntry dir : buildData.getOutputDirectories()) { |
| ICOutputEntry absoluteDir = CDataUtil.makeAbsolute(project, dir); |
| if (absoluteDir == null) |
| continue; |
| IPath dirLocation = absoluteDir.getLocation(); |
| if (dirLocation == null) |
| continue; |
| for (IFile file : files) { |
| if (dirLocation.isPrefixOf(file.getLocation())) { |
| if (buildConfig != null && buildConfig != cfgDes) { |
| // Matched more than one, so use the active configuration |
| buildConfig = null; |
| break findCfg; |
| } |
| buildConfig = cfgDes; |
| } |
| } |
| } |
| } |
| return buildConfig; |
| } |
| } |