diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/ICLIDebugActionEnabler.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/ICLIDebugActionEnabler.java new file mode 100644 index 00000000000..ed6970fbd02 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/ICLIDebugActionEnabler.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) Mar 11, 2016 QNX Software Systems. All Rights Reserved. + * + * You must obtain a written license from and pay applicable license fees to QNX + * Software Systems before you may reproduce, modify or distribute this software, + * or any work that includes all or part of this software. Free development + * licenses are available for evaluation and non-commercial purposes. For more + * information visit [http://licensing.qnx.com] or email licensing@qnx.com. + * + * This file may contain contributions from others. Please review this entire + * file for other proprietary rights or license notices, as well as the QNX + * Development Suite License Guide at [http://licensing.qnx.com/license-guide/] + * for other information. + *******************************************************************************/ +package org.eclipse.cdt.debug.core.breakpointactions; + +/** + * This interface intended to pass arbitrary debugger command to backend, + * usually intended for command line debugger or scripting. Debugger can interpret this as it see fit + * (including splitting this into multiple commands) + * + * @since 8.0 + */ +public interface ICLIDebugActionEnabler { + void execute(String command) throws Exception; +} diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.properties b/debug/org.eclipse.cdt.debug.ui/plugin.properties index 9c798eda526..01b1e40e46b 100644 --- a/debug/org.eclipse.cdt.debug.ui/plugin.properties +++ b/debug/org.eclipse.cdt.debug.ui/plugin.properties @@ -173,6 +173,7 @@ LogAction.name=Log Action ResumeAction.name=Resume Action ExternalToolAction.name=External Tool Action ReverseDebugAction.name=Reverse Debug Action +CLICommandAction.name=Debugger Command Action # Breakpoint Types breapointType.label=Type diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.xml b/debug/org.eclipse.cdt.debug.ui/plugin.xml index d31bd8b93ae..ee795660e37 100644 --- a/debug/org.eclipse.cdt.debug.ui/plugin.xml +++ b/debug/org.eclipse.cdt.debug.ui/plugin.xml @@ -1300,6 +1300,23 @@ id="org.eclipse.cdt.debug.ui.breakpointactions.ReverseDebugActionPage"> + + + + + + + + + 32) + summary = summary.substring(0, 32); + return summary; + } + + @Override + public String getTypeName() { + return Messages.getString("CLICommandAction.TypeName"); //$NON-NLS-1$ + } + + @Override + public void initializeFromMemento(String data) { + try { + Element root = DebugPlugin.parseDocument(data); + String value = root.getAttribute(COMMAND_ATT); + if (value == null) + value = ""; //$NON-NLS-1$ + command = value; + } catch (Exception e) { + CDebugUIPlugin.log(e); + } + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/CLICommandActionComposite.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/CLICommandActionComposite.java new file mode 100644 index 00000000000..2ee432bc6ba --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/CLICommandActionComposite.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2016 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: + * Alena Laskavaia (QNX)- Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.ui.breakpointactions; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + +/** + * This composite show a little text field (multi-line) that allow to enter to enter debugger commands. + * Interpretation of that depends on the backend + * + * @since 8.0 + */ +public class CLICommandActionComposite extends Composite { + private Text command; + + public CLICommandActionComposite(Composite parent, int style, CLICommandActionPage commandActionPage) { + super(parent, style); + setLayout(GridLayoutFactory.fillDefaults().create()); + Label messageToLogLabel = new Label(this, SWT.NONE); + messageToLogLabel.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create()); + messageToLogLabel.setText(Messages.getString("CLICommandActionComposite.0")); //$NON-NLS-1$ + command = new Text(this, SWT.BORDER | SWT.WRAP); + command.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create()); + command.setText(commandActionPage.getCLICommandAction().getCommand()); + } + + public String getCommand() { + return command.getText(); + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/CLICommandActionPage.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/CLICommandActionPage.java new file mode 100644 index 00000000000..7b6d606a89a --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/CLICommandActionPage.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2016 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: + * Alena Laskavaia (QNX)- Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.ui.breakpointactions; + +import org.eclipse.cdt.debug.core.breakpointactions.IBreakpointAction; +import org.eclipse.cdt.debug.ui.breakpointactions.IBreakpointActionPage; +import org.eclipse.core.runtime.PlatformObject; +import org.eclipse.swt.widgets.Composite; + +/** + * @since 8.0 + */ +public class CLICommandActionPage extends PlatformObject implements + IBreakpointActionPage { + private CLICommandAction cliCommandAction; + private CLICommandActionComposite editor; + + public CLICommandAction getCLICommandAction() { + return cliCommandAction; + } + + @Override + public void actionDialogCanceled() { + } + + @Override + public void actionDialogOK() { + cliCommandAction.setCommand(editor.getCommand()); + } + + @Override + public Composite createComposite(IBreakpointAction action, Composite composite, int style) { + cliCommandAction = (CLICommandAction) action; + editor = new CLICommandActionComposite(composite, style, this); + return editor; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/messages.properties b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/messages.properties index 7457b01b466..0f364b6fbc3 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/messages.properties +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/ui/breakpointactions/messages.properties @@ -71,3 +71,10 @@ ReverseDebugAction.error.1=Could not do reverse debug operation ReverseDebugAction.enable=Enable ReverseDebugAction.disable=Disable ReverseDebugAction.toggle=Toggle + +CLICommandActionComposite.0=Debugger command(s) to run when the breakpoint is hit: +CLICommandAction.ConsoleTitle=Debugger Command Action Messages +CLICommandAction.UntitledName=Untitled Debugger Command Action +CLICommandAction.TypeName=Debugger Command Action +CLICommandAction.error.0=Could not execute debugger command action: "{0}". +CLICommandAction.NoSupport=Your debugger integration does not support direct exectution of commands diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/breakpoint/actions/BreakpointActionAdapter.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/breakpoint/actions/BreakpointActionAdapter.java index ff9ef38922a..4ac2c735de9 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/breakpoint/actions/BreakpointActionAdapter.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/breakpoint/actions/BreakpointActionAdapter.java @@ -12,6 +12,7 @@ package org.eclipse.cdt.dsf.mi.service.breakpoint.actions; +import org.eclipse.cdt.debug.core.breakpointactions.ICLIDebugActionEnabler; import org.eclipse.cdt.debug.core.breakpointactions.ILogActionEnabler; import org.eclipse.cdt.debug.core.breakpointactions.IResumeActionEnabler; import org.eclipse.cdt.debug.core.breakpointactions.IReverseDebugEnabler; @@ -47,6 +48,9 @@ public class BreakpointActionAdapter implements IAdaptable { if (adapter.equals(IReverseDebugEnabler.class)) { return (T)new MIReverseDebugEnabler(fExecutor, fServiceTracker, fContext); } + if (adapter.equals(ICLIDebugActionEnabler.class)) { + return (T)new CLIDebugActionEnabler(fExecutor, fServiceTracker, fContext); + } return null; } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/breakpoint/actions/CLIDebugActionEnabler.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/breakpoint/actions/CLIDebugActionEnabler.java new file mode 100644 index 00000000000..9b9d651af9e --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/breakpoint/actions/CLIDebugActionEnabler.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2016 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: + * Alena Laskavaia (QNX)- Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.dsf.mi.service.breakpoint.actions; + +import org.eclipse.cdt.debug.core.breakpointactions.ICLIDebugActionEnabler; +import org.eclipse.cdt.dsf.concurrent.DsfExecutor; +import org.eclipse.cdt.dsf.concurrent.DsfRunnable; +import org.eclipse.cdt.dsf.concurrent.ImmediateDataRequestMonitor; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.debug.service.command.ICommand; +import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService; +import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext; +import org.eclipse.cdt.dsf.mi.service.command.CLIEventProcessor; +import org.eclipse.cdt.dsf.mi.service.command.commands.CLICommand; +import org.eclipse.cdt.dsf.mi.service.command.commands.MIInterpreterExecConsole; +import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo; +import org.eclipse.cdt.dsf.service.DsfServicesTracker; + +/** + * + * This class permits to execute custom user debugger commands through cli/mi bridge + * + * @since 5.0 + */ +public class CLIDebugActionEnabler implements ICLIDebugActionEnabler { + private final DsfExecutor fExecutor; + private final DsfServicesTracker fServiceTracker; + private final ICommandControlDMContext fContext; + private ICommandControlService fCommandControl; + + /** + * @param executor + * @param serviceTracker + * @param context + */ + public CLIDebugActionEnabler(DsfExecutor executor, DsfServicesTracker serviceTracker, IDMContext context) { + fExecutor = executor; + fServiceTracker = serviceTracker; + fContext = DMContexts.getAncestorOfType(context, ICommandControlDMContext.class); + fCommandControl = fServiceTracker.getService(ICommandControlService.class); + assert fContext != null; + } + + @Override + public void execute(String commandmulti) throws Exception { + String[] commands = commandmulti.split("\\r?\\n"); //$NON-NLS-1$ + for (int j = 0; j < commands.length; ++j) { + String single = commands[j]; + executeSingleCommand(single); + } + } + + private boolean isMIOperation(String operation) { + if (operation.startsWith("-")) { //$NON-NLS-1$ + return true; + } + return false; + } + + private void executeSingleCommand(String str) { + // Do not use the interpreter-exec for stepping operation the UI will fall out of step. + // Also, do not use "interpreter-exec console" for MI commands. + ICommand cmd; + if (!isMIOperation(str) && + !CLIEventProcessor.isSteppingOperation(str)) { + cmd = new MIInterpreterExecConsole<>(fContext, str); + } else { + cmd = new CLICommand<>(fContext, str); + } + fExecutor.execute(new DsfRunnable() { + @Override + public void run() { + // TODO: for print command would be nice to redirect to gdb console + fCommandControl.queueCommand(cmd, new ImmediateDataRequestMonitor<>()); + } + }); + } +}