/******************************************************************************* * 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() { 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; } }