diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.properties b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.properties index a95e4bd81b6..923aef3f505 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.properties +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2008, 2009 Ericsson and others. +# Copyright (c) 2008, 2010 Ericsson 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 @@ -22,6 +22,7 @@ launchTab.arguments.name=Arguments launchTab.debugger.name=Debugger launchTab.sourceLookup.name=Source launchTab.common.name=Common +launchTab.environment.name=Environment editorTextHover.label=GDB Debugger editorTextHover.description=Shows formatted value in debugger hover diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml index 09b60d8415d..0d1e1edf137 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/plugin.xml @@ -19,13 +19,21 @@ + + + + - + - - - - - - 0) { + fCommandControl.setEnvironment(properties, clear, requestMonitor); + } else { + requestMonitor.done(); + } + }}, /* * Enable non-stop mode if necessary */ diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend.java index e7c08175ae6..e4346d12cfd 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBBackend.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2008 Wind River Systems, Nokia and others. + * Copyright (c) 2006, 2010 Wind River Systems, 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 @@ -22,6 +22,7 @@ import java.io.Reader; import java.util.ArrayList; import java.util.Hashtable; import java.util.List; +import java.util.Properties; import java.util.concurrent.TimeUnit; import org.eclipse.cdt.core.model.ICProject; @@ -52,7 +53,10 @@ import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.variables.VariablesPlugin; import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.debug.core.ILaunchManager; import org.osgi.framework.BundleContext; /** @@ -77,6 +81,7 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend { private List fSharedLibPaths; private String fProgramArguments; + private Properties fEnvVariables; private SessionType fSessionType; private Boolean fAttach; @@ -265,6 +270,54 @@ public class GDBBackend extends AbstractDsfService implements IGDBBackend { return fSharedLibPaths; } + /** @since 3.0 */ + public Properties getEnvironmentVariables() throws CoreException { + if (fEnvVariables == null) { + fEnvVariables = new Properties(); + + // if the attribute ATTR_APPEND_ENVIRONMENT_VARIABLES is set, + // the LaunchManager will return both the new variables and the existing ones. + // That would force us to delete all the variables in GDB, and then re-create then all + // that is not very efficient. So, let's fool the LaunchManager into returning just the + // list of new variables. + + boolean append = fLaunchConfiguration.getAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, true); + + String[] properties; + if (append) { + ILaunchConfigurationWorkingCopy wc = fLaunchConfiguration.copy(""); //$NON-NLS-1$ + // Don't save this change, it is just temporary, and in just a copy of our launchConfig. + wc.setAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, false); + properties = DebugPlugin.getDefault().getLaunchManager().getEnvironment(wc); + } else { + // We're getting rid of the environment anyway, so this call will only yield the new variables. + properties = DebugPlugin.getDefault().getLaunchManager().getEnvironment(fLaunchConfiguration); + } + + if (properties == null) { + properties = new String[0]; + } + + for (String property : properties) { + int idx = property.indexOf('='); + if (idx != -1) { + String key = property.substring(0, idx); + String value = property.substring(idx + 1); + fEnvVariables.setProperty(key, value); + } else { + fEnvVariables.setProperty(property, ""); //$NON-NLS-1$ + } + } + } + + return fEnvVariables; + } + + /** @since 3.0 */ + public boolean getClearEnvironment() throws CoreException { + return !fLaunchConfiguration.getAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, true); + } + /* * Launch GDB process. * Allow subclass to override. diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IGDBBackend.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IGDBBackend.java index e7eb6061495..99e0f90d44c 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IGDBBackend.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/IGDBBackend.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008 Nokia Corporation. + * Copyright (c) 2008, 2010 Nokia Corporation. * 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 @@ -12,6 +12,7 @@ package org.eclipse.cdt.dsf.gdb.service; import java.util.List; +import java.util.Properties; import org.eclipse.cdt.dsf.mi.service.IMIBackend; import org.eclipse.core.runtime.CoreException; @@ -79,6 +80,21 @@ public interface IGDBBackend extends IMIBackend { */ public List getSharedLibraryPaths() throws CoreException; + /** + * Returns the list of user-specified variables. + * If no variables are specified, should return an empty list. + * Should not return null. + * + * @since 3.0 + */ + public Properties getEnvironmentVariables() throws CoreException; + + /** + * Returns whether the native environment should be cleared before + * setting the user-specified environment variables. + * + * @since 3.0 */ + public boolean getClearEnvironment() throws CoreException; /** * Sends an interrupt signal to the GDB process. diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl.java index ec649773b4d..dafd26667e8 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2008 Wind River Systems and others. + * Copyright (c) 2006, 2010 Wind River 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 @@ -15,10 +15,13 @@ package org.eclipse.cdt.dsf.gdb.service.command; import java.io.IOException; import java.io.OutputStream; import java.util.Hashtable; +import java.util.Properties; +import java.util.Map.Entry; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.DsfRunnable; import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants; @@ -48,11 +51,13 @@ import org.eclipse.cdt.dsf.mi.service.command.MIControlDMContext; import org.eclipse.cdt.dsf.mi.service.command.MIInferiorProcess; import org.eclipse.cdt.dsf.mi.service.command.MIRunControlEventProcessor; import org.eclipse.cdt.dsf.mi.service.command.MIInferiorProcess.State; +import org.eclipse.cdt.dsf.mi.service.command.commands.CLIUnsetEnv; import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakInsert; import org.eclipse.cdt.dsf.mi.service.command.commands.MICommand; import org.eclipse.cdt.dsf.mi.service.command.commands.MIExecContinue; import org.eclipse.cdt.dsf.mi.service.command.commands.MIExecRun; import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBExit; +import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetEnv; import org.eclipse.cdt.dsf.mi.service.command.commands.MIInferiorTTYSet; import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakInsertInfo; import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo; @@ -399,6 +404,31 @@ public class GDBControl extends AbstractMIControl implements IGDBControl { setMITracingStream(tracingStream); } + /** @since 3.0 */ + public void setEnvironment(Properties props, boolean clear, final RequestMonitor rm) { + int count = 0; + CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm); + + // First clear the environment if requested. + if (clear) { + count++; + queueCommand( + new CLIUnsetEnv(getContext()), + new DataRequestMonitor(getExecutor(), countingRm)); + } + + // Now set the new variables + for (Entry property : props.entrySet()) { + count++; + String name = (String)property.getKey(); + String value = (String)property.getValue(); + queueCommand( + new MIGDBSetEnv(getContext(), name, value), + new DataRequestMonitor(getExecutor(), countingRm)); + } + countingRm.setDoneCount(count); + } + @DsfServiceEventHandler public void eventDispatched(ICommandControlShutdownDMEvent e) { // Handle our "GDB Exited" event and stop processing commands. diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_0.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_0.java index 7dfc910331d..949503310b1 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_0.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/GDBControl_7_0.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2008 Wind River Systems and others. + * Copyright (c) 2006, 2010 Wind River 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 @@ -15,10 +15,13 @@ package org.eclipse.cdt.dsf.gdb.service.command; import java.io.IOException; import java.io.OutputStream; import java.util.Hashtable; +import java.util.Properties; +import java.util.Map.Entry; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.DsfRunnable; import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants; @@ -51,11 +54,13 @@ import org.eclipse.cdt.dsf.mi.service.command.MIControlDMContext; import org.eclipse.cdt.dsf.mi.service.command.MIInferiorProcess; import org.eclipse.cdt.dsf.mi.service.command.MIRunControlEventProcessor_7_0; import org.eclipse.cdt.dsf.mi.service.command.MIInferiorProcess.State; +import org.eclipse.cdt.dsf.mi.service.command.commands.CLIUnsetEnv; import org.eclipse.cdt.dsf.mi.service.command.commands.MIBreakInsert; import org.eclipse.cdt.dsf.mi.service.command.commands.MICommand; import org.eclipse.cdt.dsf.mi.service.command.commands.MIExecContinue; import org.eclipse.cdt.dsf.mi.service.command.commands.MIExecRun; import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBExit; +import org.eclipse.cdt.dsf.mi.service.command.commands.MIGDBSetEnv; import org.eclipse.cdt.dsf.mi.service.command.commands.MIInferiorTTYSet; import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakInsertInfo; import org.eclipse.cdt.dsf.mi.service.command.output.MIBreakpoint; @@ -533,6 +538,31 @@ public class GDBControl_7_0 extends AbstractMIControl implements IGDBControl { setMITracingStream(tracingStream); } + /** @since 3.0 */ + public void setEnvironment(Properties props, boolean clear, RequestMonitor rm) { + int count = 0; + CountingRequestMonitor countingRm = new CountingRequestMonitor(getExecutor(), rm); + + // First clear the environment if requested. + if (clear) { + count++; + queueCommand( + new CLIUnsetEnv(getContext()), + new DataRequestMonitor(getExecutor(), countingRm)); + } + + // Now set the new variables + for (Entry property : props.entrySet()) { + count++; + String name = (String)property.getKey(); + String value = (String)property.getValue(); + queueCommand( + new MIGDBSetEnv(getContext(), name, value), + new DataRequestMonitor(getExecutor(), countingRm)); + } + countingRm.setDoneCount(count); + } + @DsfServiceEventHandler public void eventDispatched(ICommandControlShutdownDMEvent e) { // Handle our "GDB Exited" event and stop processing commands. diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/IGDBControl.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/IGDBControl.java index 9cc16bff965..6eb18aad1e4 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/IGDBControl.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/command/IGDBControl.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009 Ericsson and others. + * Copyright (c) 2010 Ericsson and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse License v1.0 * which accompanies this distribution, and is available at @@ -11,6 +11,7 @@ package org.eclipse.cdt.dsf.gdb.service.command; import java.io.OutputStream; +import java.util.Properties; import org.eclipse.cdt.dsf.concurrent.RequestMonitor; import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService; @@ -40,4 +41,16 @@ public interface IGDBControl extends ICommandControlService { * @since 2.0 */ void setTracingStream(OutputStream tracingStream); + + /** + * Sets any user-defined environment variables for the inferior. + * + * If the 'clear' flag is true, all existing environment variables + * will be removed and replaced with the new specified ones. + * If 'clear' is false, the new variables are added to the existing + * environment. + * + * @since 3.0 + */ + void setEnvironment(Properties props, boolean clear, RequestMonitor requestMonitor); } \ No newline at end of file diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/CLIUnsetEnv.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/CLIUnsetEnv.java new file mode 100644 index 00000000000..b2f2c88b86e --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/CLIUnsetEnv.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2010 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.mi.service.command.commands; + +import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext; +import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo; + +/** + * + * unset env [VARNAME] + * + * Deletes the environment variable VARNAME for the inferior, not GDB itself. + * If VARNAME is omitted, all environment variables are deleted. + * + * @since 3.0 + */ +public class CLIUnsetEnv extends CLICommand { + + /** + * Delete all existing environment variables + */ + public CLIUnsetEnv(ICommandControlDMContext ctx) { + this(ctx, null); + } + + /** + * Delete the environment variable specified by 'name' + * If 'name' is null, all variables will be deleted. + */ + public CLIUnsetEnv(ICommandControlDMContext ctx, String name) { + super(ctx, "unset env " + (name != null ? name : "")); //$NON-NLS-1$ //$NON-NLS-2$ + } +} \ No newline at end of file diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIGDBSetEnv.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIGDBSetEnv.java new file mode 100644 index 00000000000..5b5254777b1 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIGDBSetEnv.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2010 Ericsson 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: + * Ericsson - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.dsf.mi.service.command.commands; + +import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext; + +/** + * + * -gdb-set env VARNAME [=VALUE] + * + * Set environment variable VARNAME to VALUE. The value changes for your program only, + * not for gdb itself. VALUE may be any string; the values of environment variables are + * just strings, and any interpretation is supplied by your program itself. The VALUE + * parameter is optional; if it is omitted, the variable is set to a null value. + * + * @since 3.0 + * + */ +public class MIGDBSetEnv extends MIGDBSet +{ + public MIGDBSetEnv(ICommandControlDMContext dmc, String name) { + this(dmc, name, null); + } + + public MIGDBSetEnv(ICommandControlDMContext dmc, String name, String value) { + super(dmc, new String[] { "env", name + (value != null && value.length() > 0 ? "=" + value : "")}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } +} \ No newline at end of file