diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildCoreTests20.java b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildCoreTests20.java index 805d83df23d..1df00d08f76 100644 --- a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildCoreTests20.java +++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/ManagedBuildCoreTests20.java @@ -51,9 +51,11 @@ import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; /* @@ -202,7 +204,7 @@ public class ManagedBuildCoreTests20 extends TestCase { /** * Convert path to OS specific representation */ - private String toOSString(String path) { + private String toOSLocation(String path) { File file = new File(path); try { path = file.getCanonicalPath(); @@ -211,7 +213,14 @@ public class ManagedBuildCoreTests20 extends TestCase { return path; } - + + /** + * Convert path to OS specific representation + */ + private String toOSString(String path) { + return new Path(path).toOSString(); + } + /** * The purpose of this test is to exercise the build path info interface. * To get to that point, a new project/config has to be created in the test @@ -232,21 +241,44 @@ public class ManagedBuildCoreTests20 extends TestCase { } //These are the expected path settings - final String[] expectedPaths = { - toOSString("/usr/include"), - toOSString("/opt/gnome/include"), - toOSString("C:\\home\\tester/include"), - // relative path makes 2 entries - project.getLocation().append("includes").toOSString(), - "includes", - "/usr/gnu/include", // This one set to ICSettingEntry.RESOLVED - }; + IPath buildCWD = project.getLocation().append("Sub Config"); + + final String[] expectedPaths; + if (new Path("C:\\home\\tester/include").isAbsolute()) { + // Windows + expectedPaths = new String[] { + toOSLocation("/usr/include"), + toOSLocation("/opt/gnome/include"), + toOSLocation("C:\\home\\tester/include"), + // relative paths from MBS will make 3 entries + project.getLocation().append("includes").toOSString(), + buildCWD.append("includes").toOSString(), + toOSString("includes"), + "/usr/gnu/include", // Not converted to OS string due to being flagged as ICSettingEntry.RESOLVED + }; + } else { + // Unix + expectedPaths = new String[] { + toOSLocation("/usr/include"), + toOSLocation("/opt/gnome/include"), + // on unix "C:\\home\\tester/include" is relative path + // looks like nonsense but has to be this way as MBS converts entry to keep "Sub Config/C:\\home\\tester/include" in its storage + project.getLocation().append("Sub Config/C:\\home\\tester/include").toOSString(), + buildCWD.append("Sub Config/C:\\home\\tester/include").toOSString(), + toOSString("Sub Config/C:\\home\\tester/include"), + // relative paths from MBS will make 3 entries + project.getLocation().append("includes").toOSString(), + buildCWD.append("includes").toOSString(), + toOSString("includes"), + "/usr/gnu/include", // Not converted to OS string due to being flagged as ICSettingEntry.RESOLVED + }; + } // Create a new managed project based on the sub project type IProjectType projType = ManagedBuildManager.getExtensionProjectType("test.sub"); assertNotNull(projType); - // Create the managed-project (.cdtbuild) for our project + // Create the managed-project for our project IManagedProject newProject = null; try { newProject = ManagedBuildManager.createManagedProject(project, projType); @@ -527,7 +559,7 @@ public class ManagedBuildCoreTests20 extends TestCase { IProjectType projType = ManagedBuildManager.getExtensionProjectType("test.root"); assertNotNull(projType); - // Create the managed-project (.cdtbuild) for our project that builds a dummy executable + // Create the managed-project for our project that builds a dummy executable IManagedProject newProject = ManagedBuildManager.createManagedProject(project, projType); assertEquals(newProject.getName(), projType.getName()); assertFalse(newProject.equals(projType)); diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Builder.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Builder.java index 9378bdf1988..3f6b3818677 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Builder.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Builder.java @@ -1841,11 +1841,10 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider // } if(!buildPath.isAbsolute()){ - buildPath = project.getFullPath().append(buildPath); IStringVariableManager mngr = VariablesPlugin.getDefault().getStringVariableManager(); - - result = buildPath.toString(); - result = mngr.generateVariableExpression("workspace_loc", result); //$NON-NLS-1$ + // build dir may not exist yet and non-existent paths will resolve to empty string by VariablesPlugin + // so append relative part outside of expression, i.e. ${workspace_loc:/Project}/BuildDir + result = mngr.generateVariableExpression("workspace_loc", project.getFullPath().toString()) + Path.SEPARATOR + buildPath.toString(); //$NON-NLS-1$ } else { result = buildPath.toString(); } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/language/settings/providers/MBSLanguageSettingsProvider.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/language/settings/providers/MBSLanguageSettingsProvider.java index 24616f8eeb7..e529345df1d 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/language/settings/providers/MBSLanguageSettingsProvider.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/language/settings/providers/MBSLanguageSettingsProvider.java @@ -22,11 +22,16 @@ import org.eclipse.cdt.core.settings.model.ICFileDescription; import org.eclipse.cdt.core.settings.model.ICFolderDescription; import org.eclipse.cdt.core.settings.model.ICLanguageSetting; import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry; +import org.eclipse.cdt.core.settings.model.ICPathEntry; import org.eclipse.cdt.core.settings.model.ICResourceDescription; import org.eclipse.cdt.core.settings.model.ICSettingBase; +import org.eclipse.cdt.core.settings.model.util.CDataUtil; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.variables.IStringVariableManager; +import org.eclipse.core.variables.VariablesPlugin; /** * Implementation of language settings provider for CDT Managed Build System. @@ -62,6 +67,20 @@ public class MBSLanguageSettingsProvider extends AbstractExecutableExtensionBase if ((kindsBits & kind) != 0) { List additions = langSetting.getSettingEntriesList(kind); for (ICLanguageSettingEntry entry : additions) { + if (entry instanceof ICPathEntry) { + // have to use getName() rather than getLocation() and not use IPath operations to avoid collapsing ".." + String pathStr = ((ICPathEntry) entry).getName(); + if (!new Path(pathStr).isAbsolute()) { + // We need to add project-rooted entry for relative path as MBS counts it this way in some UI + // The relative entry below also should be added for indexer to resolve from source file locations + IStringVariableManager mngr = VariablesPlugin.getDefault().getStringVariableManager(); + String projectRootedPath = mngr.generateVariableExpression("workspace_loc", rc.getProject().getName()) + Path.SEPARATOR + pathStr; //$NON-NLS-1$ + ICLanguageSettingEntry projectRootedEntry = (ICLanguageSettingEntry) CDataUtil.createEntry(kind, projectRootedPath, projectRootedPath, null, entry.getFlags()); + if (! list.contains(projectRootedEntry)) { + list.add(projectRootedEntry); + } + } + } if (! list.contains(entry)) { list.add(entry); } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsScannerInfoProvider.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsScannerInfoProvider.java index 2c6c4317dbb..5634f12989e 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsScannerInfoProvider.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/language/settings/providers/LanguageSettingsScannerInfoProvider.java @@ -30,10 +30,10 @@ import org.eclipse.cdt.core.parser.ExtendedScannerInfo; import org.eclipse.cdt.core.parser.IScannerInfo; import org.eclipse.cdt.core.parser.IScannerInfoChangeListener; import org.eclipse.cdt.core.parser.IScannerInfoProvider; -import org.eclipse.cdt.core.settings.model.ACPathEntry; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry; import org.eclipse.cdt.core.settings.model.ICMacroEntry; +import org.eclipse.cdt.core.settings.model.ICPathEntry; import org.eclipse.cdt.core.settings.model.ICProjectDescription; import org.eclipse.cdt.core.settings.model.ICSettingEntry; import org.eclipse.cdt.core.settings.model.util.CDataUtil; @@ -132,17 +132,15 @@ public class LanguageSettingsScannerInfoProvider implements IScannerInfoProvider return new ExtendedScannerInfo(definedMacros, includePaths, macroFiles, includeFiles, includePathsLocal); } - private IPath expandVariables(IPath path, ICConfigurationDescription cfgDescription) { - ICdtVariableManager varManager = CCorePlugin.getDefault().getCdtVariableManager(); - String pathStr = path.toString(); + private String expandVariables(String pathStr, ICConfigurationDescription cfgDescription) { try { + ICdtVariableManager varManager = CCorePlugin.getDefault().getCdtVariableManager(); pathStr = varManager.resolveValue(pathStr, "", null, cfgDescription); //$NON-NLS-1$ - } catch (CdtVariableException e) { + } catch (Exception e) { // Swallow exceptions but also log them CCorePlugin.log(e); } - IPath resolvedLoc = new Path(pathStr); - return resolvedLoc; + return pathStr; } /** @@ -151,7 +149,7 @@ public class LanguageSettingsScannerInfoProvider implements IScannerInfoProvider */ private static IPath getBuildCWD(ICConfigurationDescription cfgDescription) { IPath buildCWD = cfgDescription.getBuildSetting().getBuilderCWD(); - if (buildCWD==null) { + if (buildCWD == null) { IProject project = cfgDescription.getProjectDescription().getProject(); buildCWD = project.getLocation(); } else { @@ -195,28 +193,44 @@ public class LanguageSettingsScannerInfoProvider implements IScannerInfoProvider CCorePlugin.log(e); } // use OS file separators (i.e. '\' on Windows) - if (java.io.File.separatorChar != '/') { - location = location.replace('/', java.io.File.separatorChar); + if (java.io.File.separatorChar != IPath.SEPARATOR) { + location = location.replace(IPath.SEPARATOR, java.io.File.separatorChar); } - // note that we avoid using org.eclipse.core.runtime.Path for manipulations being careful - // to preserve "../" segments and not let collapsing them which is not correct for symbolic links. - Path locPath = new Path(location); - if (locPath.isAbsolute() && locPath.getDevice()==null) { - // prepend device (C:) for Windows + IPath locPath = new Path(location); + if (locPath.isAbsolute() && locPath.getDevice() == null) { IPath buildCWD = getBuildCWD(cfgDescription); + // prepend device (C:) for Windows String device = buildCWD.getDevice(); - if (device!=null) + if (device != null) { + // note that we avoid using org.eclipse.core.runtime.Path for manipulations being careful + // to preserve "../" segments and not let collapsing them which is not correct for symbolic links. location = device + location; + } } + if (!locPath.isAbsolute()) { // consider relative path to be from build working directory IPath buildCWD = getBuildCWD(cfgDescription); - location = buildCWD.toOSString() + locPath; + // again, we avoid using org.eclipse.core.runtime.Path for manipulations being careful + // to preserve "../" segments and not let collapsing them which is not correct for symbolic links. + location = buildCWD.addTrailingSeparator().toOSString() + location; } return location; } + /** + * Convert path delimiters to OS representation avoiding using org.eclipse.core.runtime.Path + * being careful to preserve "../" segments and not let collapsing them which is not correct for symbolic links. + */ + private String toOSString(String loc) { + // use OS file separators (i.e. '\' on Windows) + if (java.io.File.separatorChar != IPath.SEPARATOR) { + loc = loc.replace(IPath.SEPARATOR, java.io.File.separatorChar); + } + return loc; + } + /** * Convert the path entries to absolute file system locations represented as String array. * Resolve the entries which are not resolved. @@ -225,10 +239,10 @@ public class LanguageSettingsScannerInfoProvider implements IScannerInfoProvider * @param cfgDescription - configuration description for resolving entries. * @return array of the locations. */ - private String[] convertToLocations(LinkedHashSet entriesPath, ICConfigurationDescription cfgDescription){ + private String[] convertToLocations(LinkedHashSet entriesPath, ICConfigurationDescription cfgDescription) { List locations = new ArrayList(entriesPath.size()); for (ICLanguageSettingEntry entry : entriesPath) { - ACPathEntry entryPath = (ACPathEntry)entry; + ICPathEntry entryPath = (ICPathEntry)entry; if (entryPath.isValueWorkspacePath()) { ICLanguageSettingEntry[] entries = new ICLanguageSettingEntry[] {entry}; if (!entry.isResolved()) { @@ -236,7 +250,7 @@ public class LanguageSettingsScannerInfoProvider implements IScannerInfoProvider } for (ICLanguageSettingEntry resolved : entries) { - IPath loc = ((ACPathEntry) resolved).getLocation(); + IPath loc = ((ICPathEntry) resolved).getLocation(); if (loc != null) { if (checkBit(resolved.getFlags(), ICSettingEntry.FRAMEWORKS_MAC)) { // handle frameworks, see IScannerInfo.getIncludePaths() @@ -248,24 +262,25 @@ public class LanguageSettingsScannerInfoProvider implements IScannerInfoProvider } } } else { - String locStr = entryPath.getName(); + // have to use getName() rather than getLocation() to avoid collapsing ".." + String loc = entryPath.getName(); if (entryPath.isResolved()) { - locations.add(locStr); + locations.add(loc); } else { - locStr = resolveEntry(locStr, cfgDescription); - if (locStr!=null) { + loc = resolveEntry(loc, cfgDescription); + if (loc != null) { if (checkBit(entryPath.getFlags(), ICSettingEntry.FRAMEWORKS_MAC)) { // handle frameworks, see IScannerInfo.getIncludePaths() - locations.add(locStr+FRAMEWORK_HEADERS_INCLUDE); - locations.add(locStr+FRAMEWORK_PRIVATE_HEADERS_INCLUDE); + locations.add(toOSString(loc + FRAMEWORK_HEADERS_INCLUDE)); + locations.add(toOSString(loc + FRAMEWORK_PRIVATE_HEADERS_INCLUDE)); } else { - locations.add(locStr); - // add relative paths again for indexer to resolve from source file location - IPath unresolvedPath = entryPath.getLocation(); - if (!unresolvedPath.isAbsolute()) { - IPath expandedPath = expandVariables(unresolvedPath, cfgDescription); - if (!expandedPath.isAbsolute()) { - locations.add(expandedPath.toOSString()); + locations.add(toOSString(loc)); + String unresolvedPath = entryPath.getName(); + if (!new Path(unresolvedPath).isAbsolute()) { + // add relative paths again for indexer to resolve from source file location + String expandedPath = expandVariables(unresolvedPath, cfgDescription); + if (!expandedPath.isEmpty() && !new Path(expandedPath).isAbsolute()) { + locations.add(toOSString(expandedPath)); } } } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/IReverseDebugEnabler.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/IReverseDebugEnabler.java new file mode 100644 index 00000000000..0388be9291b --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/breakpointactions/IReverseDebugEnabler.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2007, 2012 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Marc Dumais (Ericsson) - initial implementation + *******************************************************************************/ + +package org.eclipse.cdt.debug.core.breakpointactions; + +/** + * @since 7.3 + */ +public interface IReverseDebugEnabler { + + /** + * Toggles the state of the reverse debugging mode. + * @throws Exception + */ + void toggle() throws Exception; + + /** + * Enables the reverse debugging mode. No effect if already enabled. + * @throws Exception + */ + void enable() throws Exception; + + /** + * Disables the reverse debugging mode. No effect if it's not enabled. + * @throws Exception + */ + void disable() throws Exception; + +} diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.properties b/debug/org.eclipse.cdt.debug.ui/plugin.properties index a68c817bb15..34cbb7d2d35 100644 --- a/debug/org.eclipse.cdt.debug.ui/plugin.properties +++ b/debug/org.eclipse.cdt.debug.ui/plugin.properties @@ -11,6 +11,7 @@ # Patrick Chuong (Texas Instruments) - Pin and Clone Supports (Bug 331781) # Dobrin Alexiev (Texas Instruments) - initial API and implementation (bug 336876) # Marc Khouzam (Ericsson) - Added support for connect command (Bug 365601) +# Marc Dumais (Ericsson) - Added support for reverse debug action (Bug 365776) ############################################################################### pluginName=C/C++ Development Tools Debugger UI @@ -37,10 +38,10 @@ ShowDebuggerConsoleAction.label=Show Debugger Console ShowDebuggerConsoleAction.tooltip=Show Debugger Console On Target Selection AddBreakpoint.label=Toggle Brea&kpoint -AddBreakpointInteractive.label=&Add Breakpoint...\tCtrl+Double Click -EnableBreakpoint.label=&Toggle Breakpoint Enabled\tShift+Double Click +AddBreakpointInteractive.label=&Add Breakpoint... +EnableBreakpoint.label=&Toggle Breakpoint Enabled BreakpointProperties.label=Breakpoint P&roperties... -RulerBreakpointProperties.label=Breakpoint P&roperties...\tCtrl+Double Click +RulerBreakpointProperties.label=Breakpoint P&roperties... BreakpointPropertiesCommand.name=C/C++ Breakpoint Properties BreakpointPropertiesCommand.description=View and edit properties for a given C/C++ breakpoint ManageFunctionBreakpointAction.label=Toggle Breakpoint @@ -157,6 +158,7 @@ SoundAction.name=Sound Action LogAction.name=Log Action ResumeAction.name=Resume Action ExternalToolAction.name=External Tool Action +ReverseDebugAction.name=Reverse Debug 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 d1ae7a9b7c4..fa6769bbf67 100644 --- a/debug/org.eclipse.cdt.debug.ui/plugin.xml +++ b/debug/org.eclipse.cdt.debug.ui/plugin.xml @@ -1710,6 +1710,14 @@ class="org.eclipse.cdt.debug.ui.breakpointactions.ExternalToolAction" id="org.eclipse.cdt.debug.ui.breakpointactions.ExternalToolAction"/> + + + + + + + + delta = new HashMap(); - delta.put(MIBreakpoints.PASS_COUNT, getProperty(attributes, MIBreakpoints.PASS_COUNT, 0)); - delta.put(MIBreakpoints.COMMANDS, getProperty(attributes, MIBreakpoints.COMMANDS, "")); //$NON-NLS-1$ - modifyBreakpoint(dmc, delta, drm, false); + // Tracepoints are created with no passcount (passcount are not + // the same thing as ignore-count, which is not supported by + // tracepoints). We have to set the passcount manually now. + // Same for commands. + Map delta = new HashMap(); + delta.put(MIBreakpoints.PASS_COUNT, getProperty(attributes, MIBreakpoints.PASS_COUNT, 0)); + delta.put(MIBreakpoints.COMMANDS, getProperty(attributes, MIBreakpoints.COMMANDS, "")); //$NON-NLS-1$ + modifyBreakpoint(dmc, delta, drm, false); } @Override 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 aa2861b5eb5..65776609cee 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2010 Ericsson and others. + * Copyright (c) 2008, 2012 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 @@ -7,12 +7,14 @@ * * Contributors: * Ericsson - Initial API and implementation + * Marc Dumais (Ericsson) - Added support for reverse debug action (Bug 365776) *******************************************************************************/ package org.eclipse.cdt.dsf.mi.service.breakpoint.actions; import org.eclipse.cdt.debug.core.breakpointactions.ILogActionEnabler; import org.eclipse.cdt.debug.core.breakpointactions.IResumeActionEnabler; +import org.eclipse.cdt.debug.core.breakpointactions.IReverseDebugEnabler; import org.eclipse.cdt.dsf.concurrent.DsfExecutor; import org.eclipse.cdt.dsf.datamodel.IDMContext; import org.eclipse.cdt.dsf.service.DsfServicesTracker; @@ -42,6 +44,9 @@ public class BreakpointActionAdapter implements IAdaptable { if (adapter.equals(IResumeActionEnabler.class)) { return new MIResumeActionEnabler(fExecutor, fServiceTracker, fContext); } + if (adapter.equals(IReverseDebugEnabler.class)) { + return new MIReverseDebugEnabler(fExecutor, fServiceTracker, fContext); + } return null; } diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/breakpoint/actions/MIReverseDebugEnabler.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/breakpoint/actions/MIReverseDebugEnabler.java new file mode 100644 index 00000000000..09873ddd9b8 --- /dev/null +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/breakpoint/actions/MIReverseDebugEnabler.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 2012 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: + * Marc Dumais (Ericsson) - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.dsf.mi.service.breakpoint.actions; + +import org.eclipse.cdt.debug.core.breakpointactions.IReverseDebugEnabler; +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.DsfExecutor; +import org.eclipse.cdt.dsf.concurrent.DsfRunnable; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext; +import org.eclipse.cdt.dsf.gdb.service.IReverseRunControl; +import org.eclipse.cdt.dsf.service.DsfServicesTracker; + + +/** + * + * This class permits to enable, disable or toggle the reverse + * debugging mode. + * + * @since 4.2 + */ +public class MIReverseDebugEnabler implements IReverseDebugEnabler { + private final DsfExecutor fExecutor; + private final DsfServicesTracker fServiceTracker; + private final ICommandControlDMContext fContext; + private static enum REVERSE_DEBUG_MODE {ENABLE, DISABLE, TOGGLE}; + + /** + * @param executor + * @param serviceTracker + * @param context + */ + public MIReverseDebugEnabler(DsfExecutor executor, DsfServicesTracker serviceTracker, IDMContext context) { + fExecutor = executor; + fServiceTracker = serviceTracker; + fContext = DMContexts.getAncestorOfType(context, ICommandControlDMContext.class); + assert fContext != null; + } + + @Override + public void enable() throws Exception { + setMode(REVERSE_DEBUG_MODE.ENABLE); + } + + @Override + public void disable() throws Exception { + setMode(REVERSE_DEBUG_MODE.DISABLE); + } + + @Override + public void toggle() throws Exception { + setMode(REVERSE_DEBUG_MODE.TOGGLE); + } + + private void setMode(final REVERSE_DEBUG_MODE mode) throws Exception { + fExecutor.execute(new DsfRunnable() { + @Override + public void run() { + final IReverseRunControl runControl = fServiceTracker.getService(IReverseRunControl.class); + if (runControl != null) { + runControl.isReverseModeEnabled(fContext, new DataRequestMonitor(fExecutor, null) { + @Override + public void handleSuccess() { + Boolean enabled = getData(); + if ( (enabled.equals(false) && mode.equals(REVERSE_DEBUG_MODE.ENABLE) ) || + (enabled.equals(true) && mode.equals(REVERSE_DEBUG_MODE.DISABLE) ) || + (mode.equals(REVERSE_DEBUG_MODE.TOGGLE)) ) + { + runControl.enableReverseMode(fContext, !enabled, new RequestMonitor(fExecutor, null)); + } + } + }); + } + } + }); + } + +} diff --git a/dsf/org.eclipse.cdt.dsf.ui/plugin.properties b/dsf/org.eclipse.cdt.dsf.ui/plugin.properties index beddd33412d..8882a84afe0 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/plugin.properties +++ b/dsf/org.eclipse.cdt.dsf.ui/plugin.properties @@ -31,9 +31,9 @@ commandContext.name= In Disassembly commandContext.description= When debugging in assembly mode # actions -action.breakpointProperties.label = Breakpoint Properties...\Ctrl+Double Click -action.toggleBreakpoint.label = Toggle Breakpoint\tDouble Click -action.addBreakpoint.label = Add Breakpoint...\tCtrl+Double Click +action.breakpointProperties.label = Breakpoint Properties... +action.toggleBreakpoint.label = Toggle Breakpoint +action.addBreakpoint.label = Add Breakpoint... menu.updatePolicy = Update Policy menu.threadsUpdatePolicy = Threads Update Policy diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyMessages.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyMessages.java index cb73691e57e..7a5d3431e77 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyMessages.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyMessages.java @@ -83,9 +83,11 @@ public final class DisassemblyMessages extends NLS { public static String Disassembly_Error_Dialog_title; public static String Disassembly_Error_Dialog_ok_button; public static String DisassemblyBackendDsf_error_UnableToRetrieveData; - public static String Disassembly_action_AddBreakpoint_label; + public static String Disassembly_action_AddBreakpoint_label; public static String Disassembly_action_AddBreakpoint_errorTitle; public static String Disassembly_action_AddBreakpoint_errorMessage; + public static String Disassembly_action_ToggleBreakpoint_accelerator; + static { NLS.initializeMessages(DisassemblyMessages.class.getName(), DisassemblyMessages.class); diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyMessages.properties b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyMessages.properties index fbe8b0b165f..b295a6056f6 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyMessages.properties +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyMessages.properties @@ -18,14 +18,15 @@ Disassembly_action_GotoPC_tooltip=Go to Current Program Counter Disassembly_action_GotoAddress_label=Go to Address... Disassembly_action_Copy_label=&Copy Disassembly_action_SelectAll_label=Select &All -Disassembly_action_BreakpointProperties_label=Breakpoint Properties...\tCtrl+Double Click -Disassembly_action_DisableBreakpoint_label=Disable Breakpoint\tShift+Double Click -Disassembly_action_EnableBreakpoint_label=Enable Breakpoint\tShift+Double Click +Disassembly_action_BreakpointProperties_label=Breakpoint Properties... +Disassembly_action_ToggleBreakpoint_accelerator=Double Click +Disassembly_action_EnableBreakpoint_label=Enable Breakpoint +Disassembly_action_DisableBreakpoint_label=Disable Breakpoint Disassembly_action_RefreshView_label=Re&fresh View Disassembly_action_OpenPreferences_label=&Preferences... Disassembly_action_Sync_label=Link with Active Debug Context Disassembly_action_TrackExpression_label=Track Expression -Disassembly_action_AddBreakpoint_label=Add Breakpoint...\tCtrl+Double Click +Disassembly_action_AddBreakpoint_label=Add Breakpoint... Disassembly_action_AddBreakpoint_errorTitle=Error Disassembly_action_AddBreakpoint_errorMessage=Unable to create breakpoint diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyPart.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyPart.java index 4b1187a6a07..dbf601e331c 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyPart.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/DisassemblyPart.java @@ -31,6 +31,7 @@ import java.util.Map; import org.eclipse.cdt.core.IAddress; import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.debug.internal.ui.CDebugUIUtils; import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.AbstractDisassemblyBackend; import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.AddressRangePosition; import org.eclipse.cdt.debug.internal.ui.disassembly.dsf.DisassemblyPosition; @@ -414,7 +415,8 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem private IBreakpoint fBreakpoint; public ActionToggleBreakpointEnablement() { super(DisassemblyPart.this); - setText(DisassemblyMessages.Disassembly_action_EnableBreakpoint_label); + setText(DisassemblyMessages.Disassembly_action_EnableBreakpoint_label + "\t" + //$NON-NLS-1$ + CDebugUIUtils.formatKeyBindingString(SWT.MOD2, DisassemblyMessages.Disassembly_action_ToggleBreakpoint_accelerator)); } @Override public void run() { @@ -436,9 +438,11 @@ public abstract class DisassemblyPart extends WorkbenchPart implements IDisassem fBreakpoint = bps[0]; try { if (fBreakpoint.isEnabled()) { - setText(DisassemblyMessages.Disassembly_action_DisableBreakpoint_label); + setText(DisassemblyMessages.Disassembly_action_DisableBreakpoint_label + "\t" + //$NON-NLS-1$ + CDebugUIUtils.formatKeyBindingString(SWT.MOD2, DisassemblyMessages.Disassembly_action_ToggleBreakpoint_accelerator)); } else { - setText(DisassemblyMessages.Disassembly_action_EnableBreakpoint_label); + setText(DisassemblyMessages.Disassembly_action_EnableBreakpoint_label + "\t" + //$NON-NLS-1$ + CDebugUIUtils.formatKeyBindingString(SWT.MOD2, DisassemblyMessages.Disassembly_action_ToggleBreakpoint_accelerator)); } } catch (CoreException e) { setEnabled(false); diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/AddBreakpointRulerAction.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/AddBreakpointRulerAction.java index 7e4df04046d..2ebc6375eec 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/AddBreakpointRulerAction.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/AddBreakpointRulerAction.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions; +import org.eclipse.cdt.debug.internal.ui.CDebugUIUtils; import org.eclipse.cdt.debug.internal.ui.actions.ActionMessages; import org.eclipse.cdt.debug.ui.CDebugUIPlugin; import org.eclipse.cdt.debug.ui.breakpoints.IToggleBreakpointsTargetCExtension; @@ -31,6 +32,7 @@ import org.eclipse.jface.text.source.IVerticalRulerInfo; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; import org.eclipse.ui.IWorkbenchPart; /** @@ -41,7 +43,8 @@ public class AddBreakpointRulerAction extends AbstractDisassemblyBreakpointRuler protected AddBreakpointRulerAction(IDisassemblyPart disassemblyPart, IVerticalRulerInfo rulerInfo) { super(disassemblyPart, rulerInfo); - setText(DisassemblyMessages.Disassembly_action_AddBreakpoint_label); + setText(DisassemblyMessages.Disassembly_action_AddBreakpoint_label + "\t" + //$NON-NLS-1$ + CDebugUIUtils.formatKeyBindingString(SWT.MOD1, DisassemblyMessages.Disassembly_action_ToggleBreakpoint_accelerator)); } /* diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/BreakpointPropertiesRulerAction.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/BreakpointPropertiesRulerAction.java index fd3010d83a9..f1acbd206a2 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/BreakpointPropertiesRulerAction.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/disassembly/actions/BreakpointPropertiesRulerAction.java @@ -11,6 +11,7 @@ package org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions; import org.eclipse.cdt.debug.core.model.ICBreakpoint; +import org.eclipse.cdt.debug.internal.ui.CDebugUIUtils; import org.eclipse.cdt.debug.ui.breakpoints.CBreakpointPropertyDialogAction; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.DisassemblyMessages; import org.eclipse.cdt.dsf.debug.internal.ui.disassembly.provisional.IDisassemblyPart; @@ -23,6 +24,7 @@ import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; import org.eclipse.ui.IWorkbenchPart; /** @@ -35,7 +37,8 @@ public class BreakpointPropertiesRulerAction extends AbstractDisassemblyBreakpoi protected BreakpointPropertiesRulerAction(IDisassemblyPart disassemblyPart, IVerticalRulerInfo rulerInfo) { super(disassemblyPart, rulerInfo); - setText(DisassemblyMessages.Disassembly_action_BreakpointProperties_label); + setText(DisassemblyMessages.Disassembly_action_BreakpointProperties_label + "\t" + //$NON-NLS-1$ + CDebugUIUtils.formatKeyBindingString(SWT.MOD1, DisassemblyMessages.Disassembly_action_ToggleBreakpoint_accelerator)); } /*