/******************************************************************************* * Copyright (c) 2014, 2014 IBM Corporation 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: * Bruno Medeiros - initial API and implementation *******************************************************************************/ package melnorme.lang.ide.debug.core; import static melnorme.utilbox.misc.StringUtil.emptyAsNull; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map.Entry; import org.eclipse.cdt.core.parser.util.StringUtil; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; import org.eclipse.cdt.dsf.debug.service.IDsfDebugServicesFactory; import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin; import org.eclipse.cdt.dsf.gdb.launching.GdbLaunch; import org.eclipse.cdt.dsf.gdb.service.GDBBackend; import org.eclipse.cdt.dsf.service.DsfSession; import org.eclipse.cdt.utils.spawner.ProcessFactory; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.core.model.ISourceLocator; import melnorme.lang.ide.core.LangCore; import melnorme.lang.ide.core.utils.ResourceUtils; import melnorme.lang.ide.debug.core.services.LangDebugServicesExtensions; import melnorme.lang.ide.launching.LaunchConstants; import melnorme.utilbox.misc.ArrayUtil; public abstract class AbstractLangDebugLaunchConfigurationDelegate extends LangLaunchConfigurationDelegate_Actual { public AbstractLangDebugLaunchConfigurationDelegate() { } protected final GdbLaunchDelegateExtension gdbLaunchDelegate = createGdbLaunchDelegate(); protected GdbLaunchDelegateExtension createGdbLaunchDelegate() { return new GdbLaunchDelegateExt(); } protected class GdbLaunchDelegateExt extends GdbLaunchDelegateExtension { @Override protected GdbLaunch createGdbLaunch(ILaunchConfiguration configuration, String mode, ISourceLocator locator) throws CoreException { return doCreateGdbLaunch(configuration, mode, locator); } @Override protected LangDebugServicesExtensions createServicesExtensions(IDsfDebugServicesFactory parentServiceFactory) { return doCreateServicesExtensions(parentServiceFactory); } } protected abstract GdbLaunch doCreateGdbLaunch(ILaunchConfiguration configuration, String mode, ISourceLocator locator); protected LangDebugServicesExtensions doCreateServicesExtensions(IDsfDebugServicesFactory parentServiceFactory) { return new LangDebugServicesExtensions(parentServiceFactory); } @Override protected ILaunch getLaunchForRunMode(ILaunchConfiguration configuration, String mode) throws CoreException { throw abort_UnsupportedMode(mode); // Run not supported } @Override public ILaunch getLaunchForDebugMode(ILaunchConfiguration configuration, String mode) throws CoreException { ILaunchConfigurationWorkingCopy workingCopy = configuration.getWorkingCopy(); setAttributes(workingCopy); workingCopy.doSave(); return gdbLaunchDelegate.getLaunch(configuration, mode); } protected void setAttributes(ILaunchConfigurationWorkingCopy workingCopy) throws CoreException { // Setup CDT config parameters workingCopy.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, processLauncher.programFileLocation.toString()); workingCopy.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, workingCopy.getAttribute(LaunchConstants.ATTR_PROGRAM_ARGUMENTS, "")); workingCopy.setAttribute(ICDTLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, processLauncher.workingDir.toString()); workingCopy.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, processLauncher.project.getName()); if(!workingCopy.hasAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN)) { workingCopy.setAttribute(ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_STOP_AT_MAIN, false); } // Note, environment is already setup, because it uses standard attributes: // ILaunchManager.ATTR_ENVIRONMENT_VARIABLES and ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES } @Override protected void launchProcess(ILaunchConfiguration configuration, ILaunch launch, IProgressMonitor monitor) throws CoreException { String mode = launch.getLaunchMode(); gdbLaunchDelegate.launch(configuration, mode, launch, monitor); } /* ----------------- ----------------- */ public static class GDBBackend_Lang extends GDBBackend { protected final ILaunchConfiguration fLaunchConfiguration; protected final IProject project; public GDBBackend_Lang(DsfSession session, ILaunchConfiguration lc) { super(session, lc); this.fLaunchConfiguration = lc; this.project = getProject(lc); } @Override protected Process launchGDBProcess(String[] commandLine) throws CoreException { String[] launchEnvironment = getGDBLaunch_().getLaunchEnvironment(); if(launchEnvironment != null) { // launchEnvironment should be usually be null GDB itself LangCore.logWarning("Ignoring previous CDT GDB launch environment"); } HashMap<String, String> envMap = new HashMap<>(System.getenv()); customizeEnvironment(envMap); launchEnvironment = convertoToEnvpFormat(envMap); try { return ProcessFactory.getFactory().exec(commandLine, launchEnvironment); } catch (IOException e) { String message = "Error while launching command: " + StringUtil.join(commandLine, " "); throw new CoreException(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, -1, message, e)); } } // duplicate of super.getGDBLaunch because it is private :/ protected GdbLaunch getGDBLaunch_() { return (GdbLaunch) getSession().getModelAdapter(ILaunch.class); } @SuppressWarnings("unused") protected void customizeEnvironment(HashMap<String, String> envMap) { } } /* ----------------- ----------------- */ public static IProject getProject(ILaunchConfiguration lc) { try { String prjName = lc.getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, (String) null); if(emptyAsNull(prjName) != null) { return ResourceUtils.getProject(prjName); } } catch(CoreException e) { } return null; } public static String[] convertoToEnvpFormat(HashMap<String, String> envMap) { List<String> envp = new ArrayList<>(envMap.size()); for(Entry<String, String> entry : envMap.entrySet()) { envp.add(entry.getKey() + "=" + entry.getValue()); } return ArrayUtil.createFrom(envp, String.class); } }