mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-22 22:22:11 +02:00
Bug 302121: Fully support gdb pretty printers
This commit is contained in:
parent
2031a8ee15
commit
1ffc84fb58
40 changed files with 3373 additions and 278 deletions
|
@ -8,6 +8,7 @@
|
|||
# Contributors:
|
||||
# Ericsson - initial API and implementation
|
||||
# IBM Corporation
|
||||
# Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
###############################################################################
|
||||
pluginName=GDB DSF Debugger Integration UI
|
||||
providerName=Eclipse CDT
|
||||
|
@ -41,3 +42,11 @@ command.nextTraceRecord.name=Next Trace Record
|
|||
command.prevTraceRecord.name=Previous Trace Record
|
||||
command.nextTraceRecord.description=Select Next Trace Record
|
||||
command.prevTraceRecord.description=Select Previous Trace Record
|
||||
|
||||
category.description = C/C++ debugging with the DSF GDB debugger
|
||||
category.name = CDT DSF-GDB - GDB Debugging
|
||||
activity.description = C/C++ debugging with the DSF GDB debugger
|
||||
activity.name = CDT DSF-GDB - GDB Debugging
|
||||
|
||||
# Pretty Printing
|
||||
action.fetchMoreChildren.label=Fetch More Children
|
||||
|
|
|
@ -459,5 +459,17 @@
|
|||
</enablement>
|
||||
</consolePageParticipant>
|
||||
</extension>
|
||||
|
||||
<extension point="org.eclipse.ui.popupMenus">
|
||||
<objectContribution
|
||||
adaptable="false"
|
||||
id="org.eclipse.cdt.dsf.gdb.ui.objectContribution.incompleteChildren"
|
||||
objectClass="org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.GdbVariableVMNode$IncompleteChildrenVMC">
|
||||
<action
|
||||
class="org.eclipse.cdt.dsf.gdb.internal.ui.actions.FetchMoreChildrenAction"
|
||||
id="org.eclipse.cdt.dsf.gdb.ui.action.fetchMoreChildren"
|
||||
label="%action.fetchMoreChildren.label"
|
||||
menubarPath="renderGroup">
|
||||
</action>
|
||||
</objectContribution>
|
||||
</extension>
|
||||
</plugin>
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010 Verigy 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:
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.internal.ui.actions;
|
||||
|
||||
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.actions.AbstractVMProviderActionDelegate;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.FetchMoreChildrenEvent;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.GdbExpressionVMProvider;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.GdbVariableVMNode;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.GdbVariableVMNode.IncompleteChildrenVMC;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.GdbVariableVMProvider;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMProvider;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
|
||||
import org.eclipse.debug.ui.contexts.DebugContextEvent;
|
||||
import org.eclipse.jface.action.IAction;
|
||||
import org.eclipse.jface.viewers.ISelection;
|
||||
import org.eclipse.jface.viewers.IStructuredSelection;
|
||||
import org.eclipse.jface.viewers.ITreeSelection;
|
||||
import org.eclipse.jface.viewers.TreePath;
|
||||
import org.eclipse.ui.IObjectActionDelegate;
|
||||
import org.eclipse.ui.IViewPart;
|
||||
import org.eclipse.ui.IWorkbenchPart;
|
||||
|
||||
/**
|
||||
* @since 3.0
|
||||
*/
|
||||
public class FetchMoreChildrenAction extends AbstractVMProviderActionDelegate
|
||||
implements IObjectActionDelegate {
|
||||
|
||||
private ISelection selection;
|
||||
|
||||
public void run(IAction action) {
|
||||
IncompleteChildrenVMC incompleteChildrenVmc = getIncompleteChildrenVMC();
|
||||
|
||||
if (incompleteChildrenVmc != null) {
|
||||
if (selection instanceof ITreeSelection) {
|
||||
ITreeSelection treeSelection = (ITreeSelection) selection;
|
||||
TreePath path = treeSelection.getPaths()[0];
|
||||
|
||||
IVMNode node = incompleteChildrenVmc.getVMNode();
|
||||
|
||||
IExpressionDMContext exprCtx = incompleteChildrenVmc.getParentDMContext();
|
||||
((GdbVariableVMNode) node).incrementChildCountLimit(exprCtx);
|
||||
final FetchMoreChildrenEvent fetchMoreChildrenEvent = new FetchMoreChildrenEvent(exprCtx, path);
|
||||
final AbstractVMProvider vmProvider = (AbstractVMProvider) getVMProvider();
|
||||
vmProvider.getExecutor().execute(new DsfRunnable() {
|
||||
public void run() {
|
||||
vmProvider.handleEvent(fetchMoreChildrenEvent);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(IViewPart view) {
|
||||
super.init(view);
|
||||
updateEnablement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debugContextChanged(DebugContextEvent event) {
|
||||
super.debugContextChanged(event);
|
||||
updateEnablement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectionChanged(IAction action, ISelection selection) {
|
||||
super.selectionChanged(action, selection);
|
||||
this.selection = selection;
|
||||
updateEnablement();
|
||||
}
|
||||
|
||||
private void updateEnablement() {
|
||||
boolean enabled = false;
|
||||
if ((getVMProvider() instanceof GdbExpressionVMProvider)
|
||||
|| (getVMProvider() instanceof GdbVariableVMProvider)) {
|
||||
enabled = (getIncompleteChildrenVMC() != null);
|
||||
}
|
||||
getAction().setEnabled(enabled);
|
||||
}
|
||||
|
||||
public void setActivePart(IAction action, IWorkbenchPart targetPart) {
|
||||
if (targetPart instanceof IViewPart) {
|
||||
init((IViewPart) targetPart);
|
||||
}
|
||||
}
|
||||
|
||||
private IncompleteChildrenVMC getIncompleteChildrenVMC() {
|
||||
if (selection instanceof IStructuredSelection) {
|
||||
IStructuredSelection ss = (IStructuredSelection) selection;
|
||||
|
||||
if (ss.size() == 1) {
|
||||
// Only single selection is supported.
|
||||
Object selectedObject = ss.getFirstElement();
|
||||
if (selectedObject instanceof IncompleteChildrenVMC) {
|
||||
return (IncompleteChildrenVMC) selectedObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Ericsson - initial API and implementation
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.internal.ui.preferences;
|
||||
|
||||
|
@ -15,9 +16,13 @@ import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
|
|||
import org.eclipse.jface.preference.BooleanFieldEditor;
|
||||
import org.eclipse.jface.preference.FieldEditorPreferencePage;
|
||||
import org.eclipse.jface.preference.IPreferenceStore;
|
||||
import org.eclipse.jface.preference.IntegerFieldEditor;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.SelectionAdapter;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Group;
|
||||
import org.eclipse.ui.IWorkbench;
|
||||
|
@ -29,6 +34,26 @@ import org.eclipse.ui.PlatformUI;
|
|||
*/
|
||||
public class GdbDebugPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
|
||||
|
||||
/**
|
||||
* A vehicle in order to be able to register a selection listener with
|
||||
* a {@link BooleanFieldEditor}.
|
||||
*/
|
||||
private class ListenableBooleanFieldEditor extends BooleanFieldEditor {
|
||||
|
||||
public ListenableBooleanFieldEditor(
|
||||
String name,
|
||||
String labelText,
|
||||
int style,
|
||||
Composite parent) {
|
||||
super(name, labelText, style, parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Button getChangeControl(Composite parent) {
|
||||
return super.getChangeControl(parent);
|
||||
}
|
||||
}
|
||||
|
||||
public GdbDebugPreferencePage() {
|
||||
super(FLAT);
|
||||
IPreferenceStore store= GdbUIPlugin.getDefault().getPreferenceStore();
|
||||
|
@ -100,6 +125,55 @@ public class GdbDebugPreferencePage extends FieldEditorPreferencePage implements
|
|||
// need to set layout again
|
||||
group.setLayout(groupLayout);
|
||||
|
||||
group = new Group(parent, SWT.NONE);
|
||||
group.setText(MessagesForPreferences.GdbDebugPreferencePage_prettyPrinting_label);
|
||||
groupLayout = new GridLayout(3, false);
|
||||
group.setLayout(groupLayout);
|
||||
group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||
|
||||
final ListenableBooleanFieldEditor enablePrettyPrintingField = new ListenableBooleanFieldEditor(
|
||||
IGdbDebugPreferenceConstants.PREF_ENABLE_PRETTY_PRINTING,
|
||||
MessagesForPreferences.GdbDebugPreferencePage_enablePrettyPrinting_label1 + "\n" //$NON-NLS-1$
|
||||
+ MessagesForPreferences.GdbDebugPreferencePage_enablePrettyPrinting_label2,
|
||||
SWT.NONE, group);
|
||||
|
||||
enablePrettyPrintingField.fillIntoGrid(group, 3);
|
||||
addField(enablePrettyPrintingField);
|
||||
|
||||
final Composite indentHelper = new Composite(group, SWT.NONE);
|
||||
GridLayout helperLayout = new GridLayout(3, false);
|
||||
indentHelper.setLayout(helperLayout);
|
||||
GridData helperData = new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1);
|
||||
helperData.horizontalIndent = 20;
|
||||
indentHelper.setLayoutData(helperData);
|
||||
|
||||
final IntegerFieldEditor childCountLimitField = new IntegerFieldEditor(
|
||||
IGdbDebugPreferenceConstants.PREF_INITIAL_CHILD_COUNT_LIMIT_FOR_COLLECTIONS,
|
||||
MessagesForPreferences.GdbDebugPreferencePage_initialChildCountLimitForCollections_label,
|
||||
indentHelper);
|
||||
|
||||
childCountLimitField.setValidRange(1, 10000);
|
||||
childCountLimitField.fillIntoGrid(indentHelper, 3);
|
||||
|
||||
IPreferenceStore store = GdbUIPlugin.getDefault().getPreferenceStore();
|
||||
boolean prettyPrintingEnabled = store
|
||||
.getBoolean(IGdbDebugPreferenceConstants.PREF_ENABLE_PRETTY_PRINTING);
|
||||
childCountLimitField.setEnabled(prettyPrintingEnabled, indentHelper);
|
||||
|
||||
addField(childCountLimitField);
|
||||
|
||||
enablePrettyPrintingField.getChangeControl(group).addSelectionListener(new SelectionAdapter() {
|
||||
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
boolean enabled = enablePrettyPrintingField.getBooleanValue();
|
||||
childCountLimitField.setEnabled(enabled, indentHelper);
|
||||
}
|
||||
});
|
||||
|
||||
// need to set layouts again
|
||||
indentHelper.setLayout(helperLayout);
|
||||
group.setLayout(groupLayout);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Ericsson - initial API and implementation
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.internal.ui.preferences;
|
||||
|
||||
|
@ -25,5 +26,7 @@ public class GdbPreferenceInitializer extends AbstractPreferenceInitializer {
|
|||
store.setDefault(IGdbDebugPreferenceConstants.PREF_TRACES_ENABLE, true);
|
||||
store.setDefault(IGdbDebugPreferenceConstants.PREF_AUTO_TERMINATE_GDB, true);
|
||||
store.setDefault(IGdbDebugPreferenceConstants.PREF_USE_INSPECTOR_HOVER, true);
|
||||
store.setDefault(IGdbDebugPreferenceConstants.PREF_ENABLE_PRETTY_PRINTING, true);
|
||||
store.setDefault(IGdbDebugPreferenceConstants.PREF_INITIAL_CHILD_COUNT_LIMIT_FOR_COLLECTIONS, 100);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Ericsson - initial API and implementation
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.internal.ui.preferences;
|
||||
|
||||
|
@ -23,6 +24,14 @@ class MessagesForPreferences extends NLS {
|
|||
public static String GdbDebugPreferencePage_autoTerminateGdb_label;
|
||||
public static String GdbDebugPreferencePage_hover_label;
|
||||
public static String GdbDebugPreferencePage_useInspectorHover_label;
|
||||
/** @since 3.0 */
|
||||
public static String GdbDebugPreferencePage_prettyPrinting_label;
|
||||
/** @since 3.0 */
|
||||
public static String GdbDebugPreferencePage_enablePrettyPrinting_label1;
|
||||
/** @since 3.0 */
|
||||
public static String GdbDebugPreferencePage_enablePrettyPrinting_label2;
|
||||
/** @since 3.0 */
|
||||
public static String GdbDebugPreferencePage_initialChildCountLimitForCollections_label;
|
||||
|
||||
static {
|
||||
// initialize resource bundle
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#
|
||||
# Contributors:
|
||||
# Ericsson - initial API and implementation
|
||||
# Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
###############################################################################
|
||||
|
||||
GdbDebugPreferencePage_description=General settings for GDB Debugging
|
||||
|
@ -19,3 +20,8 @@ GdbDebugPreferencePage_autoTerminateGdb_label=Terminate GDB when last process ex
|
|||
|
||||
GdbDebugPreferencePage_hover_label=Debug Text Hover
|
||||
GdbDebugPreferencePage_useInspectorHover_label=Use enhanced debug hover
|
||||
|
||||
GdbDebugPreferencePage_prettyPrinting_label=Pretty Printing
|
||||
GdbDebugPreferencePage_enablePrettyPrinting_label1=Enable pretty printers in variable/expression tree
|
||||
GdbDebugPreferencePage_enablePrettyPrinting_label2=(requires python-enabled GDB)
|
||||
GdbDebugPreferencePage_initialChildCountLimitForCollections_label=For collections, initially limit child count to
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010 Verigy 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:
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel;
|
||||
|
||||
import org.eclipse.cdt.dsf.datamodel.AbstractDMEvent;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
|
||||
import org.eclipse.jface.viewers.TreePath;
|
||||
|
||||
/**
|
||||
* Event to fetch additional children for and expression context.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
public class FetchMoreChildrenEvent extends AbstractDMEvent<IExpressionDMContext> {
|
||||
|
||||
private TreePath path;
|
||||
|
||||
public FetchMoreChildrenEvent(IExpressionDMContext exprCtx, TreePath path) {
|
||||
super(exprCtx);
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public TreePath getPath() {
|
||||
return path;
|
||||
}
|
||||
}
|
|
@ -8,10 +8,14 @@
|
|||
* Contributors:
|
||||
* Freescale Semiconductor - initial API and implementation
|
||||
* Axel Mueller - Bug 306555 - Add support for cast to type / view as array (IExpressions2)
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel;
|
||||
|
||||
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
|
||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.DsfCastToTypeSupport;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.ui.IDsfDebugUIConstants;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.DisabledExpressionVMNode;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.ExpressionManagerVMNode;
|
||||
|
@ -24,12 +28,23 @@ import org.eclipse.cdt.dsf.debug.ui.viewmodel.register.RegisterVMNode;
|
|||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.register.SyncRegisterDataAccess;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.SyncVariableDataAccess;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.VariableVMNode;
|
||||
import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.GdbVariableVMNode.IncompleteChildrenVMC;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.IRootVMNode;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.RootDMVMNode;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
|
||||
import org.eclipse.jface.preference.IPreferenceStore;
|
||||
import org.eclipse.jface.util.IPropertyChangeListener;
|
||||
import org.eclipse.jface.util.PropertyChangeEvent;
|
||||
import org.eclipse.jface.viewers.DoubleClickEvent;
|
||||
import org.eclipse.jface.viewers.ISelection;
|
||||
import org.eclipse.jface.viewers.IStructuredSelection;
|
||||
import org.eclipse.jface.viewers.ITreeSelection;
|
||||
import org.eclipse.jface.viewers.TreePath;
|
||||
|
||||
/**
|
||||
* A specialization of ExpressionVMProvider that uses a GDB-specific variable VM
|
||||
|
@ -38,12 +53,35 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont
|
|||
@SuppressWarnings("restriction")
|
||||
public class GdbExpressionVMProvider extends ExpressionVMProvider {
|
||||
|
||||
private IPropertyChangeListener fPreferencesListener;
|
||||
|
||||
/**
|
||||
* Constructor (passthru)
|
||||
*/
|
||||
public GdbExpressionVMProvider(AbstractVMAdapter adapter,
|
||||
IPresentationContext context, DsfSession session) {
|
||||
super(adapter, context, session);
|
||||
final IPreferenceStore store = GdbUIPlugin.getDefault().getPreferenceStore();
|
||||
|
||||
Integer childCountLimit = store.getInt(IGdbDebugPreferenceConstants.PREF_INITIAL_CHILD_COUNT_LIMIT_FOR_COLLECTIONS);
|
||||
if (childCountLimit != 0) {
|
||||
getPresentationContext().setProperty(IGdbDebugPreferenceConstants.PREF_INITIAL_CHILD_COUNT_LIMIT_FOR_COLLECTIONS,
|
||||
childCountLimit);
|
||||
}
|
||||
|
||||
fPreferencesListener = new IPropertyChangeListener() {
|
||||
public void propertyChange(final PropertyChangeEvent event) {
|
||||
handlePropertyChanged(store, event);
|
||||
}};
|
||||
store.addPropertyChangeListener(fPreferencesListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
|
||||
final IPreferenceStore store = GdbUIPlugin.getDefault().getPreferenceStore();
|
||||
store.removePropertyChangeListener(fPreferencesListener);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -126,4 +164,71 @@ public class GdbExpressionVMProvider extends ExpressionVMProvider {
|
|||
*/
|
||||
setRootNode(rootNode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEvent(Object event, final RequestMonitor rm) {
|
||||
if (event instanceof DoubleClickEvent && !isDisposed()) {
|
||||
|
||||
final ISelection selection= ((DoubleClickEvent) event).getSelection();
|
||||
if (selection instanceof IStructuredSelection) {
|
||||
|
||||
Object element= ((IStructuredSelection) selection).getFirstElement();
|
||||
if (element instanceof IncompleteChildrenVMC) {
|
||||
|
||||
IncompleteChildrenVMC incompleteChildrenVmc = ((IncompleteChildrenVMC) element);
|
||||
IVMNode node = incompleteChildrenVmc.getVMNode();
|
||||
if (node instanceof GdbVariableVMNode && node.getVMProvider() == this) {
|
||||
|
||||
if (selection instanceof ITreeSelection) {
|
||||
ITreeSelection treeSelection = (ITreeSelection) selection;
|
||||
TreePath path = treeSelection.getPaths()[0];
|
||||
|
||||
IExpressionDMContext exprCtx = incompleteChildrenVmc.getParentDMContext();
|
||||
((GdbVariableVMNode) node).incrementChildCountLimit(exprCtx);
|
||||
|
||||
// replace double click event with the fetch more children event.
|
||||
final FetchMoreChildrenEvent fetchMoreChildrenEvent = new FetchMoreChildrenEvent(
|
||||
exprCtx, path);
|
||||
getExecutor().execute(new DsfRunnable() {
|
||||
public void run() {
|
||||
handleEvent(fetchMoreChildrenEvent, rm);
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.handleEvent(event, rm);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param store
|
||||
* @param event
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
protected void handlePropertyChanged(final IPreferenceStore store, final PropertyChangeEvent event) {
|
||||
String property = event.getProperty();
|
||||
if (IGdbDebugPreferenceConstants.PREF_INITIAL_CHILD_COUNT_LIMIT_FOR_COLLECTIONS.equals(property)) {
|
||||
Integer childCountLimit = store.getInt(IGdbDebugPreferenceConstants.PREF_INITIAL_CHILD_COUNT_LIMIT_FOR_COLLECTIONS);
|
||||
|
||||
if (childCountLimit != 0) {
|
||||
getPresentationContext().setProperty(IGdbDebugPreferenceConstants.PREF_INITIAL_CHILD_COUNT_LIMIT_FOR_COLLECTIONS,
|
||||
childCountLimit);
|
||||
} else {
|
||||
getPresentationContext().setProperty(IGdbDebugPreferenceConstants.PREF_INITIAL_CHILD_COUNT_LIMIT_FOR_COLLECTIONS,
|
||||
null);
|
||||
}
|
||||
|
||||
getExecutor().execute(new DsfRunnable() {
|
||||
public void run() {
|
||||
handleEvent(event);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,23 +7,48 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Freescale Semiconductor - initial API and implementation
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.debug.internal.core.ICWatchpointTarget;
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
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.IExpressions;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMAddress;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerSuspendedDMEvent;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.expression.AbstractExpressionVMNode;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.SyncVariableDataAccess;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.VariableVMNode;
|
||||
import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
|
||||
import org.eclipse.cdt.dsf.mi.service.IMIExpressions;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.cdt.dsf.ui.concurrent.ViewerDataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMContext;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.VMChildrenUpdate;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.properties.IPropertiesUpdate;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.debug.core.model.IExpression;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenCountUpdate;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IHasChildrenUpdate;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
|
||||
import org.eclipse.jface.util.PropertyChangeEvent;
|
||||
import org.eclipse.jface.viewers.TreePath;
|
||||
|
||||
/**
|
||||
* Specialization of DSF's VariableVMNode. See
|
||||
|
@ -31,6 +56,42 @@ import org.eclipse.core.runtime.Status;
|
|||
*/
|
||||
public class GdbVariableVMNode extends VariableVMNode {
|
||||
|
||||
// Notes on gdb's pretty printer support (bug 302121):
|
||||
// If
|
||||
// - an expression has children
|
||||
// - and those children are provided by a pretty printer
|
||||
// - and the expression is not yet initialized
|
||||
// the expression might have a large number of children. Asking gdb to
|
||||
// provide all children, or even just the number of all children, will
|
||||
// lead to extremely slow response times.
|
||||
// Furthermore, there are C/C++ data structures (e.g. linked lists) that
|
||||
// can lead to endless loops if not correctly initialized and a pretty
|
||||
// printer tries to obtain the number of children. In this case, gdb
|
||||
// will never return.
|
||||
//
|
||||
// In order to address this problem, IMIExpressions deriving from
|
||||
// IExpressions has been introduced.
|
||||
// It lets the client specify a maximum number of children to be considered,
|
||||
// both when asking the number of sub-expression, or the sub-expressions
|
||||
// itself.
|
||||
//
|
||||
// The algorithm how it is used is as following:
|
||||
// - We don't show all children in the UI, but only up to a certain limit.
|
||||
// A special context type IncompleteChildrenVMC is used to show that
|
||||
// there are more children than those currently visible.
|
||||
// The user can fetch more children on demand.
|
||||
// - updateHasElementsInSessionThread asks only for up to one child.
|
||||
// - updateElementCountInSessionThread checks whether the expression
|
||||
// requires a limit on the child count limit. If yes, it asks
|
||||
// the expression service for up to limit + 1 children. The + 1
|
||||
// represent the child for the <...more children...> node. I.e.,
|
||||
// if the returned number of children is limit + 1, then there is
|
||||
// an <...more_children...> node. Otherwise, there is not.
|
||||
// - updateElementsInSessionThread sooner or later delegates to
|
||||
// fillUpdateWithVMCs. fillUpdateWithVMCs checks whether there are
|
||||
// limit + 1 children, and if so, will create an IncompleteChildrenVMC
|
||||
// for the last child, discarding the original expression context.
|
||||
|
||||
/**
|
||||
* Specialization of VariableVMNode.VariableExpressionVMC that participates
|
||||
* in the "Add Watchpoint" object contribution action.
|
||||
|
@ -98,8 +159,7 @@ public class GdbVariableVMNode extends VariableVMNode {
|
|||
@Override
|
||||
public void handleCompleted() {
|
||||
if (isSuccess()) {
|
||||
assert getData().getSize() > 0;
|
||||
request.setCanCreate(true);
|
||||
request.setCanCreate(getData().getSize() > 0);
|
||||
}
|
||||
request.setStatus(getStatus());
|
||||
request.done();
|
||||
|
@ -122,6 +182,41 @@ public class GdbVariableVMNode extends VariableVMNode {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The special context representing more children to be available.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
public class IncompleteChildrenVMC extends AbstractVMContext {
|
||||
|
||||
private IExpressionDMContext parentDmc;
|
||||
|
||||
public IncompleteChildrenVMC(IExpressionDMContext exprDmc, int childCountLimit) {
|
||||
super(GdbVariableVMNode.this);
|
||||
this.parentDmc = exprDmc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof IncompleteChildrenVMC &&
|
||||
((IncompleteChildrenVMC)obj).parentDmc.equals(parentDmc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return parentDmc.hashCode();
|
||||
}
|
||||
|
||||
public IExpressionDMContext getParentDMContext() {
|
||||
return parentDmc;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps expressions to their current limit on the maximum number of children.
|
||||
*/
|
||||
private Map<IExpressionDMContext, Integer> childCountLimits = new HashMap<IExpressionDMContext, Integer>();
|
||||
|
||||
/**
|
||||
* Utility method to create an IStatus object for an internal error
|
||||
*/
|
||||
|
@ -149,4 +244,331 @@ public class GdbVariableVMNode extends VariableVMNode {
|
|||
protected IDMVMContext createVMContext(IDMContext dmc) {
|
||||
return new GdbVariableExpressionVMC(dmc);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateHasElementsInSessionThread(final IHasChildrenUpdate update) {
|
||||
if (update.getElement() instanceof IncompleteChildrenVMC) {
|
||||
update.setHasChilren(false);
|
||||
update.done();
|
||||
return;
|
||||
}
|
||||
|
||||
super.updateHasElementsInSessionThread(update);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateElementCountInSessionThread(final IChildrenCountUpdate update) {
|
||||
// Get the data model context object for the current node in the hierarchy.
|
||||
|
||||
final IExpressionDMContext expressionDMC = findDmcInPath(update.getViewerInput(), update.getElementPath(), IExpressionDMContext.class);
|
||||
|
||||
if ( expressionDMC != null ) {
|
||||
final IExpressions expressionService = getServicesTracker().getService(IExpressions.class);
|
||||
|
||||
if (expressionService == null) {
|
||||
handleFailedUpdate(update);
|
||||
return;
|
||||
}
|
||||
|
||||
if (expressionService instanceof IMIExpressions) {
|
||||
final IMIExpressions miExpressions = (IMIExpressions) expressionService;
|
||||
|
||||
miExpressions.safeToAskForAllSubExpressions(expressionDMC,
|
||||
new ViewerDataRequestMonitor<Boolean>(getSession().getExecutor(), update) {
|
||||
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (! isSuccess()) {
|
||||
handleFailedUpdate(update);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean limitRequired = ! getData().booleanValue();
|
||||
if (limitRequired) {
|
||||
|
||||
final int childCountLimit = getOrInitChildCountLimit(expressionDMC);
|
||||
|
||||
miExpressions.getSubExpressionCount(
|
||||
expressionDMC, childCountLimit + 1,
|
||||
new ViewerDataRequestMonitor<Integer>(getExecutor(), update) {
|
||||
@Override
|
||||
public void handleCompleted() {
|
||||
if (!isSuccess()) {
|
||||
handleFailedUpdate(update);
|
||||
return;
|
||||
}
|
||||
|
||||
int childCount = getData();
|
||||
if (childCountLimit < childCount) {
|
||||
childCount = childCountLimit + 1;
|
||||
}
|
||||
|
||||
update.setChildCount(childCount);
|
||||
update.done();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
GdbVariableVMNode.super.updateElementCountInSessionThread(update);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
super.updateElementCountInSessionThread(update);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillUpdateWithVMCs(IChildrenUpdate update,
|
||||
IDMContext[] dmcs, int firstIndex) {
|
||||
super.fillUpdateWithVMCs(update, dmcs, firstIndex);
|
||||
|
||||
IExpressionDMContext expressionDMC = findDmcInPath(update.getViewerInput(), update.getElementPath(), IExpressionDMContext.class);
|
||||
|
||||
if (expressionDMC != null) {
|
||||
int childCountLimit = getChildCountLimit(expressionDMC);
|
||||
int childCount = firstIndex + update.getLength();
|
||||
if (childCountLimit < childCount) {
|
||||
update.setChild(new IncompleteChildrenVMC(expressionDMC, childCountLimit), childCountLimit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(IPropertiesUpdate[] updates) {
|
||||
List<IPropertiesUpdate> realExpressions = new ArrayList<IPropertiesUpdate>();
|
||||
|
||||
for (IPropertiesUpdate update : updates) {
|
||||
if (update.getElement() instanceof IncompleteChildrenVMC) {
|
||||
if (update.getProperties().contains(
|
||||
AbstractExpressionVMNode.PROP_ELEMENT_EXPRESSION)) {
|
||||
update.setProperty(
|
||||
AbstractExpressionVMNode.PROP_ELEMENT_EXPRESSION,
|
||||
Messages.More_Children);
|
||||
|
||||
}
|
||||
|
||||
if (update.getProperties().contains(PROP_NAME)) {
|
||||
update.setProperty(PROP_NAME, Messages.More_Children);
|
||||
}
|
||||
update.done();
|
||||
} else {
|
||||
realExpressions.add(update);
|
||||
}
|
||||
}
|
||||
|
||||
super.update(realExpressions.toArray(new IPropertiesUpdate[realExpressions.size()]));
|
||||
}
|
||||
|
||||
private int getInitialChildCountLimit() {
|
||||
Object initialLimitProperty = getVMProvider().getPresentationContext().getProperty(
|
||||
IGdbDebugPreferenceConstants.PREF_INITIAL_CHILD_COUNT_LIMIT_FOR_COLLECTIONS);
|
||||
|
||||
return (initialLimitProperty instanceof Integer) ? (Integer) initialLimitProperty
|
||||
: 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* The given expression context requires a child count limit. If a limit
|
||||
* is already available from preceding calls, obtain this limit. Otherwise
|
||||
* calculate the initial value, store it, and return it.
|
||||
*
|
||||
* @param expressionDMC
|
||||
* @return The child count limit to apply for the given expression.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
protected int getOrInitChildCountLimit(IExpressionDMContext expressionDMC) {
|
||||
if (childCountLimits.containsKey(expressionDMC)) {
|
||||
return childCountLimits.get(expressionDMC);
|
||||
}
|
||||
|
||||
int initialLimit = getInitialChildCountLimit();
|
||||
childCountLimits.put(expressionDMC, initialLimit);
|
||||
|
||||
return initialLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param expressionDMC
|
||||
* @return The currently stored child count limit for the given expression,
|
||||
* or {@link Integer#MAX_VALUE} if no child count limit is currently
|
||||
* stored.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
protected int getChildCountLimit(IExpressionDMContext expressionDMC) {
|
||||
if (childCountLimits.containsKey(expressionDMC)) {
|
||||
return childCountLimits.get(expressionDMC);
|
||||
}
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
private void resetChildCountLimits(IExecutionDMContext execCtx) {
|
||||
int initialLimit = getInitialChildCountLimit();
|
||||
for (IExpressionDMContext limitCtx : childCountLimits.keySet()) {
|
||||
if (DMContexts.isAncestorOf(limitCtx, execCtx)) {
|
||||
childCountLimits.put(limitCtx, initialLimit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void resetAllChildCountLimits() {
|
||||
int initialLimit = getInitialChildCountLimit();
|
||||
for (IExpressionDMContext limitCtx : childCountLimits.keySet()) {
|
||||
childCountLimits.put(limitCtx, initialLimit);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the child count limit by the default increment.
|
||||
* This implementation doubles the current limit.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
public void incrementChildCountLimit(IExpressionDMContext expressionDMC) {
|
||||
assert(childCountLimits.containsKey(expressionDMC));
|
||||
|
||||
int childCountLimit = getChildCountLimit(expressionDMC);
|
||||
if (childCountLimit < Integer.MAX_VALUE / 2) {
|
||||
childCountLimits.put(expressionDMC, childCountLimit * 2);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDeltaFlags(Object e) {
|
||||
int flags = super.getDeltaFlags(e);
|
||||
|
||||
if (e instanceof FetchMoreChildrenEvent) {
|
||||
flags |= IModelDelta.CONTENT;
|
||||
} else if (e instanceof ISuspendedDMEvent) {
|
||||
// The child count limit must be reset.
|
||||
flags |= IModelDelta.CONTENT;
|
||||
} else if (e instanceof PropertyChangeEvent) {
|
||||
String property = ((PropertyChangeEvent)e).getProperty();
|
||||
if (IGdbDebugPreferenceConstants.PREF_INITIAL_CHILD_COUNT_LIMIT_FOR_COLLECTIONS.equals(property))
|
||||
{
|
||||
flags |= IModelDelta.CONTENT;
|
||||
}
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getDeltaFlagsForExpression(IExpression expression, Object event) {
|
||||
int flags = super.getDeltaFlagsForExpression(expression, event);
|
||||
|
||||
if (event instanceof FetchMoreChildrenEvent) {
|
||||
flags |= IModelDelta.CONTENT;
|
||||
} else if (event instanceof PropertyChangeEvent) {
|
||||
String property = ((PropertyChangeEvent) event).getProperty();
|
||||
if (IGdbDebugPreferenceConstants.PREF_INITIAL_CHILD_COUNT_LIMIT_FOR_COLLECTIONS
|
||||
.equals(property)) {
|
||||
flags |= IModelDelta.CONTENT;
|
||||
}
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildDelta(Object e, VMDelta parentDelta, int nodeOffset,
|
||||
RequestMonitor rm) {
|
||||
|
||||
if (e instanceof FetchMoreChildrenEvent) {
|
||||
buildDeltaForFetchMoreChildrenEvent((FetchMoreChildrenEvent) e, parentDelta, rm);
|
||||
return;
|
||||
} else if (e instanceof ISuspendedDMEvent) {
|
||||
resetChildCountLimits(((ISuspendedDMEvent) e).getDMContext());
|
||||
} else if (e instanceof PropertyChangeEvent) {
|
||||
String property = ((PropertyChangeEvent)e).getProperty();
|
||||
if (IGdbDebugPreferenceConstants.PREF_INITIAL_CHILD_COUNT_LIMIT_FOR_COLLECTIONS.equals(property))
|
||||
{
|
||||
resetAllChildCountLimits();
|
||||
buildDeltaForChildCountLimitPreferenceChangedEvent(parentDelta, rm);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
super.buildDelta(e, parentDelta, nodeOffset, rm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildDeltaForExpressionElement(Object element, int elementIdx,
|
||||
Object event, VMDelta parentDelta, RequestMonitor rm) {
|
||||
|
||||
if (event instanceof FetchMoreChildrenEvent) {
|
||||
FetchMoreChildrenEvent fetchMoreEvent = (FetchMoreChildrenEvent) event;
|
||||
GdbVariableExpressionVMC topLevelExpressionVMC = (GdbVariableExpressionVMC) element;
|
||||
if (topLevelExpressionVMC.equals(fetchMoreEvent.getPath().getFirstSegment())) {
|
||||
buildDeltaForFetchMoreChildrenEvent(fetchMoreEvent, parentDelta, rm);
|
||||
return;
|
||||
}
|
||||
} else if (event instanceof ISuspendedDMEvent) {
|
||||
resetChildCountLimits(((ISuspendedDMEvent) event).getDMContext());
|
||||
} else if (event instanceof IContainerSuspendedDMEvent) {
|
||||
resetChildCountLimits(((IContainerSuspendedDMEvent) event).getDMContext());
|
||||
} else if (event instanceof PropertyChangeEvent) {
|
||||
String property = ((PropertyChangeEvent)event).getProperty();
|
||||
if (IGdbDebugPreferenceConstants.PREF_INITIAL_CHILD_COUNT_LIMIT_FOR_COLLECTIONS.equals(property))
|
||||
{
|
||||
resetAllChildCountLimits();
|
||||
buildDeltaForChildCountLimitPreferenceChangedEvent(parentDelta, rm);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
super.buildDeltaForExpressionElement(element, elementIdx, event, parentDelta,
|
||||
rm);
|
||||
}
|
||||
|
||||
private void buildDeltaForFetchMoreChildrenEvent(
|
||||
FetchMoreChildrenEvent fetchMoreChidrenEvent,
|
||||
VMDelta parentDelta, final RequestMonitor rm) {
|
||||
|
||||
TreePath path = fetchMoreChidrenEvent.getPath();
|
||||
|
||||
// Add all the parents of the expression. Those didn't change, however.
|
||||
for (int i = 0; i < path.getSegmentCount() - 2; ++i) {
|
||||
parentDelta = parentDelta.addNode(path.getSegment(i), IModelDelta.NO_CHANGE);
|
||||
}
|
||||
|
||||
// Add the node for the expression. This one changed, of course.
|
||||
final VMDelta expressionDelta =
|
||||
parentDelta.addNode(path.getSegment(path.getSegmentCount() - 2), IModelDelta.CONTENT);
|
||||
|
||||
// Make sure the element formerly know as <...more_children...> is selected
|
||||
// afterwards.
|
||||
|
||||
final int offset = getChildCountLimit(fetchMoreChidrenEvent.getDMContext()) / 2;
|
||||
// The one trailing element is to see whether there are more children.
|
||||
final int maxLength = offset + 1;
|
||||
getVMProvider().updateNode(
|
||||
this,
|
||||
new VMChildrenUpdate(
|
||||
expressionDelta, getVMProvider().getPresentationContext(), offset, maxLength,
|
||||
new DataRequestMonitor<List<Object>>(getExecutor(), rm) {
|
||||
@Override
|
||||
public void handleCompleted() {
|
||||
|
||||
// FIXME if the new child has children they do not appear because of this code.
|
||||
// final List<Object> data= getData();
|
||||
// if (data != null && data.size() != 0) {
|
||||
// expressionDelta.addNode(data.get(0), offset, IModelDelta.SELECT);
|
||||
// }
|
||||
rm.done();
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private void buildDeltaForChildCountLimitPreferenceChangedEvent(
|
||||
final VMDelta parentDelta, final RequestMonitor rm) {
|
||||
parentDelta.setFlags(parentDelta.getFlags() | IModelDelta.CONTENT);
|
||||
rm.done();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,19 +8,34 @@
|
|||
* Contributors:
|
||||
* Freescale Semiconductor - initial API and implementation
|
||||
* Axel Mueller - Bug 306555 - Add support for cast to type / view as array (IExpressions2)
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel;
|
||||
|
||||
import org.eclipse.cdt.dsf.concurrent.DsfRunnable;
|
||||
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
|
||||
import org.eclipse.cdt.dsf.debug.internal.ui.viewmodel.DsfCastToTypeSupport;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.SyncVariableDataAccess;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.VariableVMNode;
|
||||
import org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.VariableVMProvider;
|
||||
import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.GdbVariableVMNode.IncompleteChildrenVMC;
|
||||
import org.eclipse.cdt.dsf.service.DsfSession;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.AbstractVMAdapter;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.IRootVMNode;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode;
|
||||
import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.RootDMVMNode;
|
||||
import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext;
|
||||
import org.eclipse.jface.preference.IPreferenceStore;
|
||||
import org.eclipse.jface.util.IPropertyChangeListener;
|
||||
import org.eclipse.jface.util.PropertyChangeEvent;
|
||||
import org.eclipse.jface.viewers.DoubleClickEvent;
|
||||
import org.eclipse.jface.viewers.ISelection;
|
||||
import org.eclipse.jface.viewers.IStructuredSelection;
|
||||
import org.eclipse.jface.viewers.ITreeSelection;
|
||||
import org.eclipse.jface.viewers.TreePath;
|
||||
|
||||
/**
|
||||
* A specialization of VariableVMProvider that uses a GDB-specific variable VM
|
||||
|
@ -29,15 +44,39 @@ import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationCont
|
|||
@SuppressWarnings("restriction")
|
||||
public class GdbVariableVMProvider extends VariableVMProvider {
|
||||
|
||||
private IPropertyChangeListener fPreferencesListener;
|
||||
|
||||
/**
|
||||
* Constructor (passthru)
|
||||
*/
|
||||
public GdbVariableVMProvider(AbstractVMAdapter adapter,
|
||||
IPresentationContext context, DsfSession session) {
|
||||
super(adapter, context, session);
|
||||
|
||||
final IPreferenceStore store = GdbUIPlugin.getDefault().getPreferenceStore();
|
||||
|
||||
Integer childCountLimit = store.getInt(IGdbDebugPreferenceConstants.PREF_INITIAL_CHILD_COUNT_LIMIT_FOR_COLLECTIONS);
|
||||
if (childCountLimit != 0) {
|
||||
getPresentationContext().setProperty(IGdbDebugPreferenceConstants.PREF_INITIAL_CHILD_COUNT_LIMIT_FOR_COLLECTIONS,
|
||||
childCountLimit);
|
||||
}
|
||||
|
||||
fPreferencesListener = new IPropertyChangeListener() {
|
||||
public void propertyChange(final PropertyChangeEvent event) {
|
||||
handlePropertyChanged(store, event);
|
||||
}};
|
||||
store.addPropertyChangeListener(fPreferencesListener);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
|
||||
final IPreferenceStore store = GdbUIPlugin.getDefault().getPreferenceStore();
|
||||
store.removePropertyChangeListener(fPreferencesListener);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.VariableVMProvider#configureLayout(org.eclipse.cdt.dsf.debug.ui.viewmodel.variable.SyncVariableDataAccess)
|
||||
*/
|
||||
@Override
|
||||
|
@ -62,4 +101,71 @@ public class GdbVariableVMProvider extends VariableVMProvider {
|
|||
// provider will recursively drill-down the variable hierarchy.
|
||||
addChildNodes(subExpressioNode, new IVMNode[] { subExpressioNode });
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEvent(Object event, final RequestMonitor rm) {
|
||||
if (event instanceof DoubleClickEvent && !isDisposed()) {
|
||||
|
||||
final ISelection selection= ((DoubleClickEvent) event).getSelection();
|
||||
if (selection instanceof IStructuredSelection) {
|
||||
|
||||
Object element= ((IStructuredSelection) selection).getFirstElement();
|
||||
if (element instanceof IncompleteChildrenVMC) {
|
||||
|
||||
IncompleteChildrenVMC incompleteChildrenVmc = ((IncompleteChildrenVMC) element);
|
||||
IVMNode node = incompleteChildrenVmc.getVMNode();
|
||||
if (node instanceof GdbVariableVMNode && node.getVMProvider() == this) {
|
||||
|
||||
if (selection instanceof ITreeSelection) {
|
||||
|
||||
ITreeSelection treeSelection = (ITreeSelection) selection;
|
||||
TreePath path = treeSelection.getPaths()[0];
|
||||
IExpressionDMContext exprCtx = incompleteChildrenVmc.getParentDMContext();
|
||||
((GdbVariableVMNode) node).incrementChildCountLimit(exprCtx);
|
||||
|
||||
// replace double click event with the fetch more children event.
|
||||
final FetchMoreChildrenEvent fetchMoreChildrenEvent = new FetchMoreChildrenEvent(
|
||||
exprCtx, path);
|
||||
getExecutor().execute(new DsfRunnable() {
|
||||
public void run() {
|
||||
handleEvent(fetchMoreChildrenEvent, rm);
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.handleEvent(event, rm);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param store
|
||||
* @param event
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
protected void handlePropertyChanged(final IPreferenceStore store, final PropertyChangeEvent event) {
|
||||
String property = event.getProperty();
|
||||
if (IGdbDebugPreferenceConstants.PREF_INITIAL_CHILD_COUNT_LIMIT_FOR_COLLECTIONS.equals(property)) {
|
||||
Integer childCountLimit = store.getInt(IGdbDebugPreferenceConstants.PREF_INITIAL_CHILD_COUNT_LIMIT_FOR_COLLECTIONS);
|
||||
|
||||
if (childCountLimit != 0) {
|
||||
getPresentationContext().setProperty(IGdbDebugPreferenceConstants.PREF_INITIAL_CHILD_COUNT_LIMIT_FOR_COLLECTIONS,
|
||||
childCountLimit);
|
||||
} else {
|
||||
getPresentationContext().setProperty(IGdbDebugPreferenceConstants.PREF_INITIAL_CHILD_COUNT_LIMIT_FOR_COLLECTIONS,
|
||||
null);
|
||||
}
|
||||
|
||||
getExecutor().execute(new DsfRunnable() {
|
||||
public void run() {
|
||||
handleEvent(event);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,5 +7,7 @@
|
|||
#
|
||||
# Contributors:
|
||||
# IBM Corporation - initial API and implementation
|
||||
# Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
###############################################################################
|
||||
Internal_Error=Internal Error
|
||||
More_Children=<...more children...>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel;
|
||||
|
||||
|
@ -23,4 +24,5 @@ public class Messages extends NLS {
|
|||
private Messages() {}
|
||||
|
||||
public static String Internal_Error;
|
||||
public static String More_Children;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Ericsson - initial implementation
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb;
|
||||
|
||||
|
@ -36,7 +37,21 @@ public interface IGdbDebugPreferenceConstants {
|
|||
*/
|
||||
public static final String PREF_USE_INSPECTOR_HOVER = "useInspectorHover"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
/**
|
||||
* Boolean preference whether to enable pretty printers for MI variable
|
||||
* objects. Default is <code>true</code>.
|
||||
* @since 4.0
|
||||
*/
|
||||
public static final String PREF_ENABLE_PRETTY_PRINTING = "enablePrettyPrinting"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* The maximum limit of children to be initially fetched by GDB for
|
||||
* collections. Default is 100.
|
||||
* @since 4.0
|
||||
*/
|
||||
public static final String PREF_INITIAL_CHILD_COUNT_LIMIT_FOR_COLLECTIONS = "initialChildCountLimitForCollections"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Help prefixes.
|
||||
*/
|
||||
public static final String PREFIX = GdbPlugin.PLUGIN_ID + "."; //$NON-NLS-1$
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
* Ericsson - initial API and implementation
|
||||
* Nokia - create and use backend service.
|
||||
* IBM Corporation
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.launching;
|
||||
|
||||
|
@ -27,6 +28,7 @@ import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
|||
import org.eclipse.cdt.dsf.debug.service.IBreakpoints.IBreakpointsTargetDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.ISourceLookup.ISourceLookupDMContext;
|
||||
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
|
||||
import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants;
|
||||
import org.eclipse.cdt.dsf.gdb.actions.IConnect;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
|
||||
import org.eclipse.cdt.dsf.gdb.service.IGDBBackend;
|
||||
|
@ -44,6 +46,7 @@ import org.eclipse.core.runtime.CoreException;
|
|||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
import org.eclipse.debug.core.DebugPlugin;
|
||||
|
@ -76,6 +79,7 @@ public class FinalLaunchSequence extends ReflectionSequence {
|
|||
"stepInitializeFinalLaunchSequence", //$NON-NLS-1$
|
||||
"stepSetEnvironmentDirectory", //$NON-NLS-1$
|
||||
"stepSetBreakpointPending", //$NON-NLS-1$
|
||||
"stepEnablePrettyPrinting", //$NON-NLS-1$
|
||||
"stepSourceGDBInitFile", //$NON-NLS-1$
|
||||
"stepSetEnvironmentVariables", //$NON-NLS-1$
|
||||
"stepSetExecutable", //$NON-NLS-1$
|
||||
|
@ -181,6 +185,29 @@ public class FinalLaunchSequence extends ReflectionSequence {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn on pretty printers for MI variable objects, if enabled in preferences.
|
||||
* Also, turn off error messages from python, all the time.
|
||||
* @since 4.0
|
||||
*/
|
||||
@Execute
|
||||
public void stepEnablePrettyPrinting(final RequestMonitor requestMonitor) {
|
||||
if (Platform.getPreferencesService().getBoolean("org.eclipse.cdt.dsf.gdb.ui", //$NON-NLS-1$
|
||||
IGdbDebugPreferenceConstants.PREF_ENABLE_PRETTY_PRINTING,
|
||||
false, null)) {
|
||||
|
||||
fCommandControl.enablePrettyPrintingForMIVariableObjects(
|
||||
new RequestMonitor(getExecutor(), requestMonitor) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
fCommandControl.setPrintPythonErrors(false, requestMonitor);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
fCommandControl.setPrintPythonErrors(false, requestMonitor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Source the gdbinit file specified in the launch.
|
||||
* @since 4.0
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
* Ericsson - Modified for additional features in DSF Reference implementation
|
||||
* Nokia - create and use backend service.
|
||||
* Vladimir Prus (CodeSourcery) - Support for -data-read-memory-bytes (bug 322658)
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.service.command;
|
||||
|
||||
|
@ -609,4 +610,18 @@ public class GDBControl extends AbstractMIControl implements IGDBControl {
|
|||
public List<String> getFeatures() {
|
||||
return fFeatures;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
public void enablePrettyPrintingForMIVariableObjects(RequestMonitor rm) {
|
||||
rm.done();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
public void setPrintPythonErrors(boolean enabled, RequestMonitor rm) {
|
||||
rm.done();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
* Ericsson - Modified for additional features in DSF Reference implementation
|
||||
* Ericsson - New version for 7_0
|
||||
* Vladimir Prus (CodeSourcery) - Support for -data-read-memory-bytes (bug 322658)
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.service.command;
|
||||
|
||||
|
@ -783,4 +784,27 @@ public class GDBControl_7_0 extends AbstractMIControl implements IGDBControl {
|
|||
requestMonitor.done();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
public void enablePrettyPrintingForMIVariableObjects(
|
||||
final RequestMonitor rm) {
|
||||
|
||||
queueCommand(
|
||||
getCommandFactory().createMIEnablePrettyPrinting(fControlDmc),
|
||||
new DataRequestMonitor<MIInfo>(getExecutor(), rm));
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
public void setPrintPythonErrors(boolean enabled, RequestMonitor rm) {
|
||||
|
||||
String subCommand = "set python print-stack " + (enabled ? "on" : "off"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
|
||||
|
||||
queueCommand(
|
||||
getCommandFactory().createCLIMaintenance(fControlDmc, subCommand),
|
||||
new DataRequestMonitor<MIInfo>(getExecutor(), rm));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
* Contributors:
|
||||
* Ericsson - initial API and implementation
|
||||
* Vladimir Prus (CodeSourcery) - Support for -data-read-memory-bytes (bug 322658)
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.gdb.service.command;
|
||||
|
||||
|
@ -66,4 +67,25 @@ public interface IGDBControl extends IMICommandControl {
|
|||
* @since 4.0
|
||||
*/
|
||||
List<String> getFeatures();
|
||||
|
||||
/**
|
||||
* Enable the pretty printers also for MI variable objects. This basically
|
||||
* sends -enable-pretty-printing.
|
||||
*
|
||||
* @param rm
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
void enablePrettyPrintingForMIVariableObjects(RequestMonitor rm);
|
||||
|
||||
/**
|
||||
* Turns the printing of python errors on or off.
|
||||
*
|
||||
* @param enabled
|
||||
* If <code>true</code>, printing errors is turned on.
|
||||
* @param rm
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
void setPrintPythonErrors(boolean enabled, RequestMonitor rm);
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010 Verigy 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:
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.mi.service;
|
||||
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions3;
|
||||
|
||||
/**
|
||||
* An extension of {@link IExpressions} which became necessary because the MI
|
||||
* implementation of {@link IExpressions} has problems if asked for all
|
||||
* sub-expressions. Problems may arise if uninitialized data objects are
|
||||
* inspected. In the worst case, pretty printers may run into endless loops
|
||||
* (e.g. linked list that become cycle), and gdb never returns. But also in the
|
||||
* normal case of uninitialized collections, you easily end up with millions of
|
||||
* useless elements, damaging the responsiveness of the workbench.
|
||||
*
|
||||
* In order to avoid those problems, this extension lets the client specify a
|
||||
* maximum number of children that it is interested in.
|
||||
*
|
||||
* If you have an instance implementing {@link IExpressions}, you should always
|
||||
* check whether it implements this extension, and if so, use the methods of the
|
||||
* extension.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public interface IMIExpressions extends IExpressions3 {
|
||||
|
||||
/**
|
||||
* A special constant that can be used in methods that expect a child count
|
||||
* limit. If this constant is passed, the implementation will use the most
|
||||
* recent child count limit for the expression. If such a limit was never
|
||||
* specified before, at least one child will be fetched in order to tell
|
||||
* whether an expression has children or not.
|
||||
*/
|
||||
public static final int CHILD_COUNT_LIMIT_UNSPECIFIED = -1;
|
||||
|
||||
/**
|
||||
* This method indicates whether the given expression can safely be asked
|
||||
* for all its sub-expressions.
|
||||
*
|
||||
* If this method returns <code>false</code>, this has the following impact:
|
||||
* <ul>
|
||||
* <li>you should not call
|
||||
* {@link IExpressions#getSubExpressionCount(IExpressionDMContext, DataRequestMonitor)},
|
||||
* but
|
||||
* {@link IMIExpressions#getSubExpressionCount(IExpressionDMContext, int, DataRequestMonitor)}
|
||||
* instead.</li>
|
||||
*
|
||||
* <li>you should not call
|
||||
* {@link IExpressions#getSubExpressions(IExpressionDMContext, DataRequestMonitor)},
|
||||
* but
|
||||
* {@link IExpressions#getSubExpressions(IExpressionDMContext, int, int, DataRequestMonitor)}
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* @param exprCtx
|
||||
* The data model context representing an expression.
|
||||
*
|
||||
* @param rm
|
||||
* Data Request monitor containing <code>true</code> if this expression can
|
||||
* safely fetch all its sub-expressions. <code>false</false> otherwise.
|
||||
*/
|
||||
public void safeToAskForAllSubExpressions(IExpressionDMContext exprCtx,
|
||||
DataRequestMonitor<Boolean> rm);
|
||||
|
||||
/**
|
||||
* This method is the same as
|
||||
* {@link IExpressions#getSubExpressionCount(org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext, DataRequestMonitor)}
|
||||
* , with the slight but important difference that this method allows to
|
||||
* provide an upper limit of children we are interested in.
|
||||
* As long as {@link #safeToAskForAllSubExpressions(org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext, DataRequestMonitor)}
|
||||
* returns true, the original method can be called, and this method is not of further interest.
|
||||
* However, if {@link #safeToAskForAllSubExpressions(org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext, DataRequestMonitor)}
|
||||
* returns false, the original method must not be called, and this method must instead be used.
|
||||
* Otherwise, the gdb response time may be very slow, or it even may hang.
|
||||
*
|
||||
* @param exprCtx
|
||||
* The data model context representing an expression.
|
||||
*
|
||||
* @param maxNumberOfChildren
|
||||
* The implementation needs not check whether there are more than
|
||||
* this number of children. However, if the implementation has
|
||||
* already knowledge of more children than this, or can obtain
|
||||
* them equally efficient, it might also return a higher count.
|
||||
*
|
||||
* @param rm
|
||||
* Request completion monitor containing the number of
|
||||
* sub-expressions of the specified expression
|
||||
*/
|
||||
void getSubExpressionCount(IExpressionDMContext exprCtx,
|
||||
int maxNumberOfChildren, DataRequestMonitor<Integer> rm);
|
||||
}
|
|
@ -7,8 +7,9 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Wind River Systems - initial API and implementation
|
||||
* Ericsson - Modified for handling of multiple execution contexts
|
||||
* Ericsson - Modified for handling of multiple execution contexts
|
||||
* Axel Mueller - Bug 306555 - Add support for cast to type / view as array (IExpressions2)
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.mi.service;
|
||||
|
||||
|
@ -26,7 +27,6 @@ import org.eclipse.cdt.dsf.datamodel.IDMContext;
|
|||
import org.eclipse.cdt.dsf.debug.service.ICachingService;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions2;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions3;
|
||||
import org.eclipse.cdt.dsf.debug.service.IFormattedValues;
|
||||
import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryChangedEvent;
|
||||
import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext;
|
||||
|
@ -68,7 +68,7 @@ import org.osgi.framework.BundleContext;
|
|||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public class MIExpressions extends AbstractDsfService implements IExpressions3, ICachingService {
|
||||
public class MIExpressions extends AbstractDsfService implements IMIExpressions, ICachingService {
|
||||
|
||||
/**
|
||||
* A format that gives more details about an expression and supports pretty-printing
|
||||
|
@ -93,12 +93,28 @@ public class MIExpressions extends AbstractDsfService implements IExpressions3,
|
|||
public static class ExpressionInfo {
|
||||
private final String fullExpression;
|
||||
private final String relativeExpression;
|
||||
|
||||
private boolean isDynamic = false;
|
||||
private ExpressionInfo parent;
|
||||
private int indexInParent = -1;
|
||||
private int childCountLimit = IMIExpressions.CHILD_COUNT_LIMIT_UNSPECIFIED;
|
||||
|
||||
public ExpressionInfo(String full, String relative) {
|
||||
fullExpression = full;
|
||||
relativeExpression = relative;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
public ExpressionInfo(String full, String relative, boolean isDynamic,
|
||||
ExpressionInfo parent, int indexInParent) {
|
||||
fullExpression = full;
|
||||
relativeExpression = relative;
|
||||
this.isDynamic = isDynamic;
|
||||
this.parent = parent;
|
||||
this.indexInParent = indexInParent;
|
||||
}
|
||||
|
||||
public String getFullExpr() { return fullExpression; }
|
||||
public String getRelExpr() { return relativeExpression; }
|
||||
|
||||
|
@ -109,6 +125,7 @@ public class MIExpressions extends AbstractDsfService implements IExpressions3,
|
|||
fullExpression.equals(((ExpressionInfo) other).fullExpression)) {
|
||||
if (relativeExpression == null ? ((ExpressionInfo) other).relativeExpression == null :
|
||||
relativeExpression.equals(((ExpressionInfo) other).relativeExpression)) {
|
||||
// The other members don't play any role for equality.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -120,13 +137,98 @@ public class MIExpressions extends AbstractDsfService implements IExpressions3,
|
|||
public int hashCode() {
|
||||
return (fullExpression == null ? 0 : fullExpression.hashCode()) ^
|
||||
(relativeExpression == null ? 0 : relativeExpression.hashCode());
|
||||
// The other members don't play any role for equality.
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[" + fullExpression +", " + relativeExpression + "]"; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
|
||||
return "[" + fullExpression +", " + relativeExpression + ", isDynamic=" + isDynamic + "]"; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The parent expression info, if existing.
|
||||
* @since 4.0
|
||||
*/
|
||||
public ExpressionInfo getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The index in the child array of the parent. Only valid if
|
||||
* {@link #getParent()} returns not null.
|
||||
* @since 4.0
|
||||
*/
|
||||
public int getIndexInParentExpression() {
|
||||
return indexInParent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether the corresponding variable object is dynamic,
|
||||
* i.e. it's value and children are provided by a pretty printer.
|
||||
* @since 4.0
|
||||
*/
|
||||
public boolean isDynamic() {
|
||||
return isDynamic;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether the expression info has any ancestor that is dynamic.
|
||||
* @since 4.0
|
||||
*/
|
||||
public boolean hasDynamicAncestor() {
|
||||
for (ExpressionInfo parent = getParent(); parent != null; parent = parent.getParent()) {
|
||||
if (parent.isDynamic()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param isDynamic
|
||||
* Whether the value and children of this expression is
|
||||
* currently provided by a pretty printer or not.
|
||||
* @since 4.0
|
||||
*/
|
||||
public void setDynamic(boolean isDynamic) {
|
||||
this.isDynamic = isDynamic;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param parent The new parent expression info.
|
||||
* @since 4.0
|
||||
*/
|
||||
public void setParent(ExpressionInfo parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param index The index in the children array of the parent.
|
||||
* @since 4.0
|
||||
*/
|
||||
public void setIndexInParent(int index) {
|
||||
this.indexInParent = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The current limit on the number of children to be fetched.
|
||||
* @since 4.0
|
||||
*/
|
||||
public int getChildCountLimit() {
|
||||
return childCountLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param newLimit
|
||||
* The new limit on the number of children to be fetched.
|
||||
* @since 4.0
|
||||
*/
|
||||
public void setChildCountLimit(int newLimit) {
|
||||
this.childCountLimit = newLimit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class represents an expression.
|
||||
*/
|
||||
|
@ -188,8 +290,32 @@ public class MIExpressions extends AbstractDsfService implements IExpressions3,
|
|||
}
|
||||
|
||||
private MIExpressionDMC(String sessionId, String expr, String relExpr, IDMContext parent) {
|
||||
this(sessionId, new ExpressionInfo(expr, relExpr), parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* ExpressionDMC Constructor for expression to be evaluated in context
|
||||
* of a stack frame.
|
||||
*
|
||||
* @param sessionId
|
||||
* The session ID in which this context is created.
|
||||
* @param info
|
||||
* The expression info that this expression is to use.
|
||||
* @param frameCtx
|
||||
* The parent stack frame context for this ExpressionDMC.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public MIExpressionDMC(String sessionId, ExpressionInfo info, IFrameDMContext frameCtx) {
|
||||
this(sessionId, info, (IDMContext)frameCtx);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
private MIExpressionDMC(String sessionId, ExpressionInfo info, IDMContext parent) {
|
||||
super(sessionId, new IDMContext[] { parent });
|
||||
exprInfo = new ExpressionInfo(expr, relExpr);
|
||||
exprInfo = info;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -232,6 +358,26 @@ public class MIExpressions extends AbstractDsfService implements IExpressions3,
|
|||
public String getRelativeExpression() {
|
||||
return exprInfo.getRelExpr();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Get the expression info for this context.
|
||||
* @since 4.0
|
||||
*/
|
||||
public ExpressionInfo getExpressionInfo() {
|
||||
return exprInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param info
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public void setExpressionInfo(ExpressionInfo info) {
|
||||
assert (this.exprInfo.getFullExpr().equals(info.getFullExpr()));
|
||||
assert (this.exprInfo.getRelExpr().equals(info.getRelExpr()));
|
||||
|
||||
this.exprInfo = info;
|
||||
}
|
||||
}
|
||||
|
||||
protected static class InvalidContextExpressionDMC extends AbstractDMContext
|
||||
|
@ -313,7 +459,27 @@ public class MIExpressions extends AbstractDsfService implements IExpressions3,
|
|||
return (fAddr == null ? "null" : "(" + fAddr.toHexAddressString()) + ", " + fSize + ")"; //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If an expressions doesn't have an address, or it cannot be determined,
|
||||
* use this class.
|
||||
* @since 4.0
|
||||
*/
|
||||
protected class InvalidDMAddress implements IExpressionDMLocation {
|
||||
|
||||
public IAddress getAddress() {
|
||||
return IExpressions.IExpressionDMLocation.INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public String getLocation() {
|
||||
return ""; //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class represents the static data referenced by an instance of ExpressionDMC,
|
||||
* such as its type and number of children; it does not contain the value or format
|
||||
|
@ -552,8 +718,6 @@ public class MIExpressions extends AbstractDsfService implements IExpressions3,
|
|||
* This method shuts down this service. It unregisters the service, stops
|
||||
* receiving service events, and calls the superclass shutdown() method to
|
||||
* finish the shutdown process.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
@Override
|
||||
public void shutdown(RequestMonitor requestMonitor) {
|
||||
|
@ -582,9 +746,18 @@ public class MIExpressions extends AbstractDsfService implements IExpressions3,
|
|||
* Create an expression context.
|
||||
*/
|
||||
public IExpressionDMContext createExpression(IDMContext ctx, String expression, String relExpr) {
|
||||
return createExpression(ctx, new ExpressionInfo(expression, relExpr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an expression context from a given expression info.
|
||||
* @since 4.0
|
||||
*/
|
||||
private IExpressionDMContext createExpression(IDMContext ctx, ExpressionInfo info) {
|
||||
String expression = info.getFullExpr();
|
||||
IFrameDMContext frameDmc = DMContexts.getAncestorOfType(ctx, IFrameDMContext.class);
|
||||
if (frameDmc != null) {
|
||||
return new MIExpressionDMC(getSession().getId(), expression, relExpr, frameDmc);
|
||||
return new MIExpressionDMC(getSession().getId(), info, frameDmc);
|
||||
}
|
||||
|
||||
IMIExecutionDMContext execCtx = DMContexts.getAncestorOfType(ctx, IMIExecutionDMContext.class);
|
||||
|
@ -595,7 +768,7 @@ public class MIExpressions extends AbstractDsfService implements IExpressions3,
|
|||
MIStack stackService = getServicesTracker().getService(MIStack.class);
|
||||
if (stackService != null) {
|
||||
frameDmc = stackService.createFrameDMContext(execCtx, 0);
|
||||
return new MIExpressionDMC(getSession().getId(), expression, relExpr, frameDmc);
|
||||
return new MIExpressionDMC(getSession().getId(), info, frameDmc);
|
||||
}
|
||||
|
||||
return new InvalidContextExpressionDMC(getSession().getId(), expression, execCtx);
|
||||
|
@ -603,7 +776,7 @@ public class MIExpressions extends AbstractDsfService implements IExpressions3,
|
|||
|
||||
IMemoryDMContext memoryCtx = DMContexts.getAncestorOfType(ctx, IMemoryDMContext.class);
|
||||
if (memoryCtx != null) {
|
||||
return new MIExpressionDMC(getSession().getId(), expression, relExpr, memoryCtx);
|
||||
return new MIExpressionDMC(getSession().getId(), info, memoryCtx);
|
||||
}
|
||||
|
||||
// Don't care about the relative expression at this point
|
||||
|
@ -662,7 +835,8 @@ public class MIExpressions extends AbstractDsfService implements IExpressions3,
|
|||
fExpressionCache.execute(
|
||||
new ExprMetaGetVar(dmc),
|
||||
new DataRequestMonitor<ExprMetaGetVarInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
IExpressionDMData.BasicType basicType = null;
|
||||
|
||||
|
@ -682,7 +856,10 @@ public class MIExpressions extends AbstractDsfService implements IExpressions3,
|
|||
break;
|
||||
case GDBType.GENERIC:
|
||||
default:
|
||||
if (getData().getNumChildren() > 0) {
|
||||
// The interesting question is not hasChildren,
|
||||
// but canHaveChildren. E.g. an empty
|
||||
// collection still is a composite.
|
||||
if (getData().hasChildren() || getData().getCollectionHint()) {
|
||||
basicType = IExpressionDMData.BasicType.composite;
|
||||
} else {
|
||||
basicType = IExpressionDMData.BasicType.basic;
|
||||
|
@ -718,6 +895,17 @@ public class MIExpressions extends AbstractDsfService implements IExpressions3,
|
|||
IExpressionDMContext dmc,
|
||||
final DataRequestMonitor<IExpressionDMAddress> rm) {
|
||||
|
||||
if (dmc instanceof MIExpressionDMC) {
|
||||
MIExpressionDMC miDMC = (MIExpressionDMC) dmc;
|
||||
if (miDMC.getExpressionInfo().hasDynamicAncestor()) {
|
||||
// For children of dynamic varobjs, there is no full expression that gdb
|
||||
// could evaluate in order to provide address and size.
|
||||
rm.setData(new InvalidDMAddress());
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// First create an address expression and a size expression
|
||||
// to be used in back-end calls
|
||||
final IExpressionDMContext addressDmc =
|
||||
|
@ -778,37 +966,45 @@ public class MIExpressions extends AbstractDsfService implements IExpressions3,
|
|||
{
|
||||
// We need to make sure the FormattedValueDMContext also holds an ExpressionContext,
|
||||
// or else this method cannot do its work.
|
||||
// Note that we look for MIExpressionDMC and not IExpressionDMC, because getting
|
||||
// Note that we look for MIExpressionDMC and not IExpressionDMC, because
|
||||
// looking for IExpressionDMC could yield InvalidContextExpressionDMC which is still
|
||||
// not what we need to have.
|
||||
// not what we need.
|
||||
MIExpressionDMC exprDmc = DMContexts.getAncestorOfType(dmc, MIExpressionDMC.class);
|
||||
if (exprDmc == null ) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context for evaluating expressions.", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
} else {
|
||||
if (DETAILS_FORMAT.equals(dmc.getFormatID())) {
|
||||
// This format is obtained through a different GDB command.
|
||||
// It yields more details than the variableObject output.
|
||||
// Starting with GDB 7.0, this format automatically supports pretty-printing, as long as
|
||||
// GDB has been configured to support it.
|
||||
fExpressionCache.execute(
|
||||
fCommandFactory.createMIDataEvaluateExpression(exprDmc),
|
||||
new DataRequestMonitor<MIDataEvaluateExpressionInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
rm.setData(new FormattedValueDMData(getData().getValue()));
|
||||
rm.done();
|
||||
}
|
||||
@Override
|
||||
protected void handleError() {
|
||||
if (fTraceVisualization) {
|
||||
rm.setData(new FormattedValueDMData("")); //$NON-NLS-1$
|
||||
rm.done();
|
||||
} else {
|
||||
super.handleError();
|
||||
}
|
||||
}
|
||||
});
|
||||
if (exprDmc.getExpressionInfo().hasDynamicAncestor()) {
|
||||
// -data-evaluate-expression does not work for children of
|
||||
// dynamic varobjs, since there is no full expression
|
||||
// that gdb could evaluate.
|
||||
rm.setData(new FormattedValueDMData(Messages.MIExpressions_NotAvailableBecauseChildOfDynamicVarobj));
|
||||
rm.done();
|
||||
} else {
|
||||
// This format is obtained through a different GDB command.
|
||||
// It yields more details than the variableObject output.
|
||||
// Starting with GDB 7.0, this format automatically supports pretty-printing, as long as
|
||||
// GDB has been configured to support it.
|
||||
fExpressionCache.execute(
|
||||
fCommandFactory.createMIDataEvaluateExpression(exprDmc),
|
||||
new DataRequestMonitor<MIDataEvaluateExpressionInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
rm.setData(new FormattedValueDMData(getData().getValue()));
|
||||
rm.done();
|
||||
}
|
||||
@Override
|
||||
protected void handleError() {
|
||||
if (fTraceVisualization) {
|
||||
rm.setData(new FormattedValueDMData("")); //$NON-NLS-1$
|
||||
rm.done();
|
||||
} else {
|
||||
super.handleError();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
fExpressionCache.execute(
|
||||
new ExprMetaGetValue(dmc),
|
||||
|
@ -838,7 +1034,7 @@ public class MIExpressions extends AbstractDsfService implements IExpressions3,
|
|||
/**
|
||||
* Retrieves the children expressions of the specified expression
|
||||
*
|
||||
* @param exprCtx
|
||||
* @param dmc
|
||||
* The context for the expression for which the children
|
||||
* should be retrieved.
|
||||
* @param rm
|
||||
|
@ -857,9 +1053,7 @@ public class MIExpressions extends AbstractDsfService implements IExpressions3,
|
|||
IExpressionDMContext[] childArray = new IExpressionDMContext[childrenExpr.length];
|
||||
for (int i=0; i<childArray.length; i++) {
|
||||
childArray[i] = createExpression(
|
||||
dmc.getParents()[0],
|
||||
childrenExpr[i].getFullExpr(),
|
||||
childrenExpr[i].getRelExpr());
|
||||
dmc.getParents()[0], childrenExpr[i]);
|
||||
}
|
||||
|
||||
rm.setData(childArray);
|
||||
|
@ -890,7 +1084,7 @@ public class MIExpressions extends AbstractDsfService implements IExpressions3,
|
|||
* @param rm
|
||||
* The data request monitor that will contain the requested data
|
||||
*/
|
||||
public void getSubExpressions(IExpressionDMContext exprCtx, final int startIndex,
|
||||
public void getSubExpressions(final IExpressionDMContext exprCtx, final int startIndex,
|
||||
final int length, final DataRequestMonitor<IExpressionDMContext[]> rm) {
|
||||
|
||||
if (startIndex < 0 || length < 0) {
|
||||
|
@ -900,28 +1094,27 @@ public class MIExpressions extends AbstractDsfService implements IExpressions3,
|
|||
}
|
||||
|
||||
if (exprCtx instanceof MIExpressionDMC) {
|
||||
getSubExpressions(
|
||||
exprCtx,
|
||||
new DataRequestMonitor<IExpressionDMContext[]>(getExecutor(), rm) {
|
||||
fExpressionCache.execute(
|
||||
new ExprMetaGetChildren(exprCtx, startIndex + length),
|
||||
new DataRequestMonitor<ExprMetaGetChildrenInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
IExpressionDMContext[] subExpressions = getData();
|
||||
ExpressionInfo[] childrenExpr = getData().getChildrenExpressions();
|
||||
|
||||
if (startIndex >= subExpressions.length) {
|
||||
if (startIndex >= childrenExpr.length) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, REQUEST_FAILED, "Invalid range for evaluating sub expressions.", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
return;
|
||||
}
|
||||
|
||||
int realLength = length;
|
||||
if (startIndex + length > subExpressions.length) {
|
||||
realLength = subExpressions.length - startIndex;
|
||||
}
|
||||
|
||||
IExpressionDMContext[] subRange = new IExpressionDMContext[realLength];
|
||||
System.arraycopy(subExpressions, startIndex, subRange, 0, realLength);
|
||||
|
||||
rm.setData(subRange);
|
||||
int numChildren = childrenExpr.length - startIndex;
|
||||
numChildren = Math.min(length, numChildren);
|
||||
IExpressionDMContext[] childrenArray = new IExpressionDMContext[numChildren];
|
||||
for (int i=0; i < numChildren; i++) {
|
||||
childrenArray[i] = createExpression(
|
||||
exprCtx.getParents()[0], childrenExpr[startIndex + i]);
|
||||
}
|
||||
rm.setData(childrenArray);
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
|
@ -935,20 +1128,40 @@ public class MIExpressions extends AbstractDsfService implements IExpressions3,
|
|||
}
|
||||
|
||||
/**
|
||||
* Retrieves the count of children expressions of the specified expression
|
||||
*
|
||||
* @param exprCtx
|
||||
* The context for the expression for which the children count
|
||||
* should be retrieved.
|
||||
* @param rm
|
||||
* The data request monitor that will contain the requested data
|
||||
* @since 4.0
|
||||
*/
|
||||
public void safeToAskForAllSubExpressions(IExpressionDMContext dmc,
|
||||
final DataRequestMonitor<Boolean> rm) {
|
||||
if (dmc instanceof MIExpressionDMC) {
|
||||
fExpressionCache.execute(
|
||||
new ExprMetaGetVar(dmc),
|
||||
new DataRequestMonitor<ExprMetaGetVarInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
boolean safe = getData().isSafeToAskForAllChildren();
|
||||
|
||||
rm.setData(safe);
|
||||
rm.done();
|
||||
}
|
||||
});
|
||||
} else if (dmc instanceof InvalidContextExpressionDMC) {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Invalid context for evaluating expressions.", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
} else {
|
||||
rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Invalid expression context.", null)); //$NON-NLS-1$
|
||||
rm.done();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
public void getSubExpressionCount(IExpressionDMContext dmc,
|
||||
final DataRequestMonitor<Integer> rm)
|
||||
{
|
||||
final int numChildLimit, final DataRequestMonitor<Integer> rm) {
|
||||
|
||||
if (dmc instanceof MIExpressionDMC) {
|
||||
fExpressionCache.execute(
|
||||
new ExprMetaGetChildCount(dmc),
|
||||
new ExprMetaGetChildCount(dmc, numChildLimit),
|
||||
new DataRequestMonitor<ExprMetaGetChildCountInfo>(getExecutor(), rm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
|
@ -964,13 +1177,28 @@ public class MIExpressions extends AbstractDsfService implements IExpressions3,
|
|||
rm.done();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the count of children expressions of the specified expression
|
||||
*
|
||||
* @param dmc
|
||||
* The context for the expression for which the children count
|
||||
* should be retrieved.
|
||||
* @param rm
|
||||
* The data request monitor that will contain the requested data
|
||||
*/
|
||||
public void getSubExpressionCount(IExpressionDMContext dmc,
|
||||
final DataRequestMonitor<Integer> rm)
|
||||
{
|
||||
getSubExpressionCount(dmc, IMIExpressions.CHILD_COUNT_LIMIT_UNSPECIFIED, rm);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method indicates if an expression can be written to.
|
||||
*
|
||||
* @param dmc: The data model context representing an expression.
|
||||
* @param dmc The data model context representing an expression.
|
||||
*
|
||||
* @param rm: Data Request monitor containing True if this expression's value can be edited. False otherwise.
|
||||
* @param rm Data Request monitor containing True if this expression's value can be edited. False otherwise.
|
||||
*/
|
||||
|
||||
public void canWriteExpression(IExpressionDMContext dmc, final DataRequestMonitor<Boolean> rm) {
|
||||
|
@ -997,7 +1225,7 @@ public class MIExpressions extends AbstractDsfService implements IExpressions3,
|
|||
/**
|
||||
* Changes the value of the specified expression based on the new value and format.
|
||||
*
|
||||
* @param expressionContext
|
||||
* @param dmc
|
||||
* The context for the expression for which the value
|
||||
* should be changed.
|
||||
* @param expressionValue
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Ericsson - initial API and implementation
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.mi.service;
|
||||
|
||||
|
@ -19,6 +20,7 @@ import org.eclipse.osgi.util.NLS;
|
|||
class Messages extends NLS {
|
||||
public static String Breakpoint_attribute_problem;
|
||||
public static String Breakpoint_installation_failed;
|
||||
public static String MIExpressions_NotAvailableBecauseChildOfDynamicVarobj;
|
||||
|
||||
static {
|
||||
// initialize resource bundle
|
||||
|
|
|
@ -7,7 +7,10 @@
|
|||
#
|
||||
# Contributors:
|
||||
# Ericsson - initial API and implementation
|
||||
# Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
###############################################################################
|
||||
|
||||
Breakpoint_attribute_problem=Breakpoint attribute problem: {0}
|
||||
Breakpoint_installation_failed=installation failed
|
||||
|
||||
MIExpressions_NotAvailableBecauseChildOfDynamicVarobj=N/A (child of pretty-printed object)
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
* Ericsson - Implementation for DSF-GDB
|
||||
* Anna Dushistova (Mentor Graphics) - [318322] Add set solib-absolute-prefix
|
||||
* Vladimir Prus (CodeSourcery) - Support for -data-read-memory-bytes (bug 322658)
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.dsf.mi.service.command;
|
||||
|
@ -36,6 +37,7 @@ import org.eclipse.cdt.dsf.mi.service.command.commands.CLIInfoProgram;
|
|||
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIInfoSharedLibrary;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIInfoThreads;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIJump;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIMaintenance;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIPasscount;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.CLIRecord;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.CLISource;
|
||||
|
@ -60,6 +62,7 @@ import org.eclipse.cdt.dsf.mi.service.command.commands.MIDataListRegisterValues;
|
|||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIDataReadMemory;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIDataReadMemoryBytes;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIDataWriteMemory;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIEnablePrettyPrinting;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIEnvironmentCD;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIEnvironmentDirectory;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIExecContinue;
|
||||
|
@ -133,6 +136,7 @@ import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarInfoPathExpression;
|
|||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarInfoType;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarListChildren;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarSetFormat;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarSetUpdateRange;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarShowAttributes;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarShowFormat;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.MIVarUpdate;
|
||||
|
@ -229,6 +233,11 @@ public class CommandFactory {
|
|||
return new CLIJump(ctx, location);
|
||||
}
|
||||
|
||||
/** @since 4.0 */
|
||||
public ICommand<MIInfo> createCLIMaintenance(ICommandControlDMContext ctx, String subCommand) {
|
||||
return new CLIMaintenance(ctx, subCommand);
|
||||
}
|
||||
|
||||
public ICommand<MIInfo> createCLIPasscount(IBreakpointsTargetDMContext ctx, int breakpoint, int passcount) {
|
||||
return new CLIPasscount(ctx, breakpoint, passcount);
|
||||
}
|
||||
|
@ -375,6 +384,11 @@ public class CommandFactory {
|
|||
return new MIDataWriteMemory(ctx, offset, address, wordFormat, wordSize, value);
|
||||
}
|
||||
|
||||
/** @since 4.0 */
|
||||
public ICommand<MIInfo> createMIEnablePrettyPrinting(ICommandControlDMContext ctx) {
|
||||
return new MIEnablePrettyPrinting(ctx);
|
||||
}
|
||||
|
||||
public ICommand<MIInfo> createMIEnvironmentCD(ICommandControlDMContext ctx, String path) {
|
||||
return new MIEnvironmentCD(ctx, path);
|
||||
}
|
||||
|
@ -801,10 +815,20 @@ public class CommandFactory {
|
|||
return new MIVarListChildren(ctx, name);
|
||||
}
|
||||
|
||||
/** @since 4.0 */
|
||||
public ICommand<MIVarListChildrenInfo> createMIVarListChildren(ICommandControlDMContext ctx, String name, int from, int to) {
|
||||
return new MIVarListChildren(ctx, name, from, to);
|
||||
}
|
||||
|
||||
public ICommand<MIVarSetFormatInfo> createMIVarSetFormat(ICommandControlDMContext ctx, String name, String fmt) {
|
||||
return new MIVarSetFormat(ctx, name, fmt);
|
||||
}
|
||||
|
||||
/** @since 4.0 */
|
||||
public ICommand<MIInfo> createMIVarSetUpdateRange(ICommandControlDMContext ctx,String name, int from, int to) {
|
||||
return new MIVarSetUpdateRange(ctx, name, from, to);
|
||||
}
|
||||
|
||||
public ICommand<MIVarShowAttributesInfo> createMIVarShowAttributes(ICommandControlDMContext ctx, String name) {
|
||||
return new MIVarShowAttributes(ctx, name);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010 Verigy 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:
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
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;
|
||||
|
||||
/**
|
||||
* Executes "maintenance" command.
|
||||
* @since 4.0
|
||||
*/
|
||||
public class CLIMaintenance extends CLICommand<MIInfo> {
|
||||
|
||||
public CLIMaintenance(ICommandControlDMContext ctx, String arguments) {
|
||||
super(ctx, "maintenance " + arguments); //$NON-NLS-1$
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007, 2009 Ericsson and others.
|
||||
* Copyright (c) 2007, 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
|
||||
|
@ -7,15 +7,57 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Ericsson - initial API and implementation
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.mi.service.command.commands;
|
||||
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
|
||||
import org.eclipse.cdt.dsf.mi.service.IMIExpressions;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.ExprMetaGetChildCountInfo;
|
||||
|
||||
public class ExprMetaGetChildCount extends ExprMetaCommand<ExprMetaGetChildCountInfo> {
|
||||
|
||||
private int numChildLimit = IMIExpressions.CHILD_COUNT_LIMIT_UNSPECIFIED;
|
||||
|
||||
public ExprMetaGetChildCount(IExpressionDMContext ctx) {
|
||||
super(ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ctx
|
||||
* @param numChildLimit
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public ExprMetaGetChildCount(IExpressionDMContext ctx, int numChildLimit) {
|
||||
super(ctx);
|
||||
this.numChildLimit = numChildLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
public int getNumChildLimit() {
|
||||
return numChildLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + numChildLimit;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
return false;
|
||||
ExprMetaGetChildCount other = (ExprMetaGetChildCount) obj;
|
||||
if (numChildLimit != other.numChildLimit)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007, 2009 Ericsson and others.
|
||||
* Copyright (c) 2007, 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
|
||||
|
@ -7,15 +7,57 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Ericsson - initial API and implementation
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.mi.service.command.commands;
|
||||
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
|
||||
import org.eclipse.cdt.dsf.mi.service.IMIExpressions;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.ExprMetaGetChildrenInfo;
|
||||
|
||||
public class ExprMetaGetChildren extends ExprMetaCommand<ExprMetaGetChildrenInfo> {
|
||||
|
||||
private int numChildLimit = IMIExpressions.CHILD_COUNT_LIMIT_UNSPECIFIED;
|
||||
|
||||
public ExprMetaGetChildren(IExpressionDMContext ctx) {
|
||||
super(ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ctx
|
||||
* @param numChildLimit
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public ExprMetaGetChildren(IExpressionDMContext ctx, int numChildLimit) {
|
||||
super(ctx);
|
||||
this.numChildLimit = numChildLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
public int getNumChildLimit() {
|
||||
return numChildLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + numChildLimit;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (!super.equals(obj))
|
||||
return false;
|
||||
ExprMetaGetChildren other = (ExprMetaGetChildren) obj;
|
||||
if (numChildLimit != other.numChildLimit)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010 Verigy 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:
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
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;
|
||||
|
||||
/**
|
||||
* -enable-pretty-printing
|
||||
*
|
||||
* Enables Python based Pretty printing
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public class MIEnablePrettyPrinting extends MICommand<MIInfo>
|
||||
{
|
||||
/**
|
||||
* @param dmc
|
||||
*/
|
||||
public MIEnablePrettyPrinting(ICommandControlDMContext dmc) {
|
||||
super(dmc, "-enable-pretty-printing"); //$NON-NLS-1$
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2009 QNX Software Systems and others.
|
||||
* Copyright (c) 2000, 2010 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
|
||||
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.dsf.mi.service.command.commands;
|
||||
|
@ -17,12 +18,15 @@ import org.eclipse.cdt.dsf.mi.service.command.output.MIVarInfoNumChildrenInfo;
|
|||
|
||||
/**
|
||||
*
|
||||
* -var-info-num-children NAME
|
||||
*
|
||||
* Returns the number of children of a variable object NAME:
|
||||
*
|
||||
* numchild=N
|
||||
* -var-info-num-children NAME
|
||||
*
|
||||
* Returns the number of children of a variable object NAME:
|
||||
*
|
||||
* numchild=N
|
||||
*
|
||||
* Note that this number is not completely reliable for a dynamic varobjs. It
|
||||
* will return the current number of children, but more children may be
|
||||
* available.
|
||||
*/
|
||||
public class MIVarInfoNumChildren extends MICommand<MIVarInfoNumChildrenInfo>
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2009 Ericsson and others.
|
||||
* Copyright (c) 2009, 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
|
||||
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Ericsson - Initial API and implementation
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.dsf.mi.service.command.commands;
|
||||
|
@ -25,7 +26,9 @@ import org.eclipse.cdt.dsf.mi.service.command.output.MIVarInfoPathExpressionInfo
|
|||
*
|
||||
* (gdb) -var-info-path-expression C.Base.public.m_size
|
||||
* ^done,path_expr=((Base)c).m_size)
|
||||
*
|
||||
*
|
||||
* Cannot be used for dynamic varobjs, or varobjs that have a dynamic varobj
|
||||
* as ancestor.
|
||||
*/
|
||||
|
||||
public class MIVarInfoPathExpression extends MICommand<MIVarInfoPathExpressionInfo>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2009 QNX Software Systems and others.
|
||||
* Copyright (c) 2009, 2010 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
|
||||
|
@ -8,6 +8,7 @@
|
|||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
* Ericsson - Modified for handling of frame contexts
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.dsf.mi.service.command.commands;
|
||||
|
@ -35,6 +36,21 @@ public class MIVarListChildren extends MICommand<MIVarListChildrenInfo>
|
|||
public MIVarListChildren(ICommandControlDMContext ctx, String name) {
|
||||
super(ctx, "-var-list-children", new String[]{name}); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ctx
|
||||
* @param name
|
||||
* @param from
|
||||
* The index of the first child to be listed, if there is one
|
||||
* with this index.
|
||||
* @param to
|
||||
* One behind the last child to be listed.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public MIVarListChildren(ICommandControlDMContext ctx, String name, int from, int to) {
|
||||
super(ctx, "-var-list-children", new String[]{name, String.valueOf(from), String.valueOf(to)}); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
@Override
|
||||
public MIVarListChildrenInfo getResult(MIOutput out) {
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010 Verigy 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:
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
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;
|
||||
|
||||
/**
|
||||
* -var-set-update-range name from to
|
||||
*
|
||||
* Set the range of children to be returned by future invocations of
|
||||
* -var-update.
|
||||
*
|
||||
* <code>from</code> and <code>to</code> indicate the range of children to
|
||||
* report in subsequent -var-update call. If from or to is less than zero, the
|
||||
* range is reset and all children will be reported. Otherwise, children
|
||||
* starting at from (zero-based) and up to and excluding to will be reported.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public class MIVarSetUpdateRange extends MICommand<MIInfo> {
|
||||
|
||||
/**
|
||||
* @param ctx
|
||||
* @param name The name of the varobj for which the range is set.
|
||||
* @param from Index of the first child to be updated with future -var-update.
|
||||
* @param to One behind the last child to be updated.
|
||||
*/
|
||||
public MIVarSetUpdateRange(ICommandControlDMContext ctx, String name, int from, int to) {
|
||||
super(ctx, "-var-set-update-range", new String[]{name, String.valueOf(from), String.valueOf(to)}); //$NON-NLS-1$
|
||||
}
|
||||
}
|
|
@ -7,21 +7,26 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Ericsson - initial API and implementation
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.mi.service.command.output;
|
||||
|
||||
import org.eclipse.cdt.dsf.debug.service.command.ICommand;
|
||||
import org.eclipse.cdt.dsf.debug.service.command.ICommandResult;
|
||||
import org.eclipse.cdt.dsf.gdb.GDBTypeParser.GDBType;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.commands.ExprMetaGetChildCount;
|
||||
|
||||
public class ExprMetaGetVarInfo implements ICommandResult {
|
||||
|
||||
private final String expression;
|
||||
private final int numChild;
|
||||
private final int numChildHint;
|
||||
private final String type;
|
||||
private final boolean editable;
|
||||
private final GDBType gdbType;
|
||||
|
||||
/** If <code>true</code>, the variable is a collection, i.e. it may have children. */
|
||||
private final boolean isCollectionHint;
|
||||
private final boolean isSafeToAskForAllChildren;
|
||||
|
||||
public ExprMetaGetVarInfo(String e, int n, String t, boolean edit) {
|
||||
this (e, n, t, null, edit);
|
||||
}
|
||||
|
@ -30,30 +35,92 @@ public class ExprMetaGetVarInfo implements ICommandResult {
|
|||
* @since 3.0
|
||||
*/
|
||||
public ExprMetaGetVarInfo(String e, int n, String t, GDBType gt, boolean edit) {
|
||||
this(e, true, n, t, gt, edit, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
public ExprMetaGetVarInfo(String e, boolean isSafeToAskForAllChildren, int n,
|
||||
String t, GDBType gt, boolean edit, boolean isCollectionHint) {
|
||||
expression = e;
|
||||
numChild = n;
|
||||
this.isSafeToAskForAllChildren = isSafeToAskForAllChildren;
|
||||
numChildHint = n;
|
||||
type = t;
|
||||
editable = edit;
|
||||
gdbType = gt;
|
||||
this.isCollectionHint = isCollectionHint;
|
||||
}
|
||||
|
||||
public String getExpr() { return expression; }
|
||||
public int getNumChildren() { return numChild; }
|
||||
|
||||
/**
|
||||
* This method only returns a 'hint' to the number of children. In the case
|
||||
* of C++ complex structures, this number will not be the actual number of
|
||||
* children. This is because GDB considers 'private/protected/public' as an
|
||||
* actual level of children, but we do not.
|
||||
* In case of variable backed by a pretty printer, the number represents
|
||||
* only the number of currently fetched children, not all children that
|
||||
* might be available.
|
||||
*
|
||||
* @return The hint on the number of children.
|
||||
*
|
||||
* @deprecated Its not possible to tell the exact number of children, but
|
||||
* you can use {@link #hasChildren()} in order to find out
|
||||
* whether the variable has children at all. In order to find
|
||||
* out about the correct number of children, use {@link ExprMetaGetChildCount}.
|
||||
*/
|
||||
@Deprecated
|
||||
public int getNumChildren() { return numChildHint; }
|
||||
|
||||
/**
|
||||
* @return Whether the variable has children or not (reliable).
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public boolean hasChildren() {
|
||||
return (numChildHint > 0);
|
||||
}
|
||||
|
||||
public String getType() { return type; }
|
||||
|
||||
/**
|
||||
* @since 3.0
|
||||
*/
|
||||
public GDBType getGDBType() { return gdbType; }
|
||||
|
||||
public boolean getEditable() { return editable; }
|
||||
|
||||
|
||||
/**
|
||||
* @return If <code>true</code>, the variable is definitely a collection,
|
||||
* if <code>false</code>, it's most probably not.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public boolean getCollectionHint() {
|
||||
return isCollectionHint;
|
||||
}
|
||||
|
||||
public <V extends ICommandResult> V getSubsetResult(ICommand<V> command) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether this variable can be safely ask for all its children, or
|
||||
* whether clients need to specify a limit on the number of children
|
||||
* to be fetched, because otherwise the gdb might hang up.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public boolean isSafeToAskForAllChildren() {
|
||||
return isSafeToAskForAllChildren;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + " (" + //$NON-NLS-1$
|
||||
getExpr() + ", " + getNumChildren() + ", " + //$NON-NLS-1$ //$NON-NLS-2$
|
||||
getType() + ", " + getEditable() + ")"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
getType() + ", " + getEditable() + ", " + //$NON-NLS-1$ //$NON-NLS-2$
|
||||
getCollectionHint() + ")"; //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010 Verigy 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:
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.mi.service.command.output;
|
||||
|
||||
/**
|
||||
* Some utilities around the display hint provided by the python pretty printers
|
||||
* via MI.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public class MIDisplayHint {
|
||||
|
||||
public static final MIDisplayHint NONE = new MIDisplayHint(GdbDisplayHint.GDB_DISPLAY_HINT_NONE, ""); //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* The set of display hints that are of particular interest to DSF GDB.
|
||||
*/
|
||||
public enum GdbDisplayHint {
|
||||
|
||||
/**
|
||||
* No hint given.
|
||||
*/
|
||||
GDB_DISPLAY_HINT_NONE(null),
|
||||
|
||||
/**
|
||||
* Display an expression or variable as string. Strings don't have children.
|
||||
*/
|
||||
GDB_DISPLAY_HINT_STRING("string"), //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Display an expression or variable as array.
|
||||
*/
|
||||
GDB_DISPLAY_HINT_ARRAY("array"), //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Display an expression or variable as map. This means each child with an
|
||||
* odd index is a key, each child with an even index is the corresponding
|
||||
* value.
|
||||
*/
|
||||
GDB_DISPLAY_HINT_MAP("map"), //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* A user defined hint. It has no further meaning to gdb.
|
||||
*/
|
||||
GDB_DISPLAY_USER_DEFINED(null);
|
||||
|
||||
private final String miToken;
|
||||
|
||||
private GdbDisplayHint(String miToken) {
|
||||
this.miToken = miToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The string that is used by MI to denote this display hint, if
|
||||
* any.
|
||||
*/
|
||||
public String getMIToken() {
|
||||
return miToken;
|
||||
}
|
||||
}
|
||||
|
||||
private final GdbDisplayHint gdbHint;
|
||||
|
||||
private final String displayHint;
|
||||
|
||||
private MIDisplayHint(GdbDisplayHint gdbHint, String hint) {
|
||||
this.gdbHint = gdbHint;
|
||||
this.displayHint = hint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the hint from the given string.
|
||||
*
|
||||
* @param text The string representation to parse in order to initialize from.
|
||||
*/
|
||||
public MIDisplayHint(String text) {
|
||||
gdbHint = parseDisplayHint(text);
|
||||
displayHint = text.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The display hint as returned by the pretty printer printer.
|
||||
*/
|
||||
public String getDisplayHint() {
|
||||
return displayHint;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return One of the display hints that are of particular interest to DSF GDB.
|
||||
*/
|
||||
public GdbDisplayHint getGdbDisplayHint() {
|
||||
return gdbHint;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return If <code>true</code>, the variable is definitely a collection,
|
||||
* if <code>false</code>, it still might be a collection.
|
||||
*/
|
||||
public boolean isCollectionHint() {
|
||||
switch(getGdbDisplayHint()) {
|
||||
case GDB_DISPLAY_HINT_ARRAY:
|
||||
case GDB_DISPLAY_HINT_MAP:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param text
|
||||
* The snipped from the MI response.
|
||||
* @return The decoded display hint predefined by gdb.
|
||||
*/
|
||||
private static GdbDisplayHint parseDisplayHint(String text) {
|
||||
|
||||
String hint = text.trim();
|
||||
|
||||
for (GdbDisplayHint gdbHint : GdbDisplayHint.values()) {
|
||||
String miToken = gdbHint.getMIToken();
|
||||
if (miToken != null && miToken.equals(hint)) {
|
||||
return gdbHint;
|
||||
}
|
||||
}
|
||||
|
||||
return GdbDisplayHint.GDB_DISPLAY_USER_DEFINED;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2009 QNX Software Systems and others.
|
||||
* Copyright (c) 2000, 2010 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
|
||||
|
@ -8,28 +8,73 @@
|
|||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
* Wind River Systems - Modified for new DSF Reference Implementation
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.dsf.mi.service.command.output;
|
||||
|
||||
|
||||
/**
|
||||
* GDB/MI var-list-children
|
||||
* -var-list-children var2
|
||||
* ^done,numchild="6",children={child={name="var2.0",exp="0",numchild="0",type="char"},child={name="var2.1",exp="1",numchild="0",type="char"},child={name="var2.2",exp="2",numchild="0",type="char"},child={name="var2.3",exp="3",numchild="0",type="char"},child={name="var2.4",exp="4",numchild="0",type="char"},child={name="var2.5",exp="5",numchild="0",type="char"}}
|
||||
*
|
||||
*
|
||||
* -var-list-children var3
|
||||
* ^done,numchild="3",displayhint="array",children=[child={name="var6.[0].[1]",exp="[1]",numchild="0",type="std::basic_string<char, std::char_traits<char>, std::allocator<char> >",thread-id="1"\
|
||||
,displayhint="string",dynamic="1"},child={name="var6.[0].[2]",exp="[2]",numchild="0",type="std::basic_string<char, std::char_traits<char>, std::allocator<char> >",thread-id="1",displayhint="string",dy\
|
||||
namic="1"},child={name="var6.[0].[3]",exp="[3]",numchild="0",type="std::basic_string<char, std::char_traits<char>, std::allocator<char> >",thread-id="1",displayhint="string",dynamic="1"}],has_more="0"\
|
||||
*/
|
||||
public class MIVar {
|
||||
|
||||
String name = ""; //$NON-NLS-1$
|
||||
String type = ""; //$NON-NLS-1$
|
||||
String exp = ""; //$NON-NLS-1$
|
||||
private boolean isDynamic = false;
|
||||
int numchild;
|
||||
|
||||
private boolean hasMore = false;
|
||||
private MIDisplayHint displayHint = MIDisplayHint.NONE;
|
||||
|
||||
public MIVar(String n, int num, String t) {
|
||||
this(n, false, num, false, t, MIDisplayHint.NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param n
|
||||
* @param isDynamic
|
||||
* @param num
|
||||
* If isDynamic is true, the number of children currently fetched
|
||||
* by gdb.
|
||||
* @param hasMore
|
||||
* If isDynamic is true, whether there are more children
|
||||
* available than just <code>num</code>.
|
||||
* @param t
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public MIVar(String n, boolean isDynamic, int num, boolean hasMore, String t) {
|
||||
this(n, isDynamic, num, hasMore, t, MIDisplayHint.NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param n
|
||||
* @param isDynamic
|
||||
* @param num
|
||||
* If isDynamic is true, the number of children currently fetched
|
||||
* by gdb.
|
||||
* @param hasMore
|
||||
* If isDynamic is true, whether there are more children
|
||||
* available than just <code>num</code>.
|
||||
* @param t
|
||||
* @param displayHint
|
||||
* @since 4.0
|
||||
*/
|
||||
public MIVar(String n, boolean isDynamic, int num, boolean hasMore, String t, MIDisplayHint displayHint) {
|
||||
name = n;
|
||||
this.isDynamic = isDynamic;
|
||||
numchild = num;
|
||||
this.hasMore = hasMore;
|
||||
type = t;
|
||||
this.displayHint = displayHint;
|
||||
}
|
||||
|
||||
public MIVar(MITuple tuple) {
|
||||
|
@ -44,14 +89,52 @@ public class MIVar {
|
|||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether the value and children of this variable are provided
|
||||
* by a pretty printer.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public boolean isDynamic() {
|
||||
return isDynamic;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The number of children. If {@link #isDynamic()} returns true,
|
||||
* the returned value only reflects the number of children currently
|
||||
* fetched by gdb. Check {@link #hasMore()} in order to find out
|
||||
* whether the are more children.
|
||||
*/
|
||||
public int getNumChild() {
|
||||
return numchild;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return For dynamic varobjs ({@link #isDynamic() returns true} this
|
||||
* method returns whether there are children in addition to the
|
||||
* currently fetched, i.e. whether there are more children than
|
||||
* {@link #getNumChild()} returns.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public boolean hasMore() {
|
||||
return hasMore;
|
||||
}
|
||||
|
||||
public String getExp() {
|
||||
return exp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether the underlying value conceptually represents a string,
|
||||
* array, or map.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public MIDisplayHint getDisplayHint() {
|
||||
return displayHint;
|
||||
}
|
||||
|
||||
void parse(MITuple tuple) {
|
||||
MIResult[] results = tuple.getMIResults();
|
||||
for (int i = 0; i < results.length; i++) {
|
||||
|
@ -73,6 +156,12 @@ public class MIVar {
|
|||
type = str;
|
||||
} else if (var.equals("exp")) { //$NON-NLS-1$
|
||||
exp = str;
|
||||
} else if (var.equals("dynamic") && str.trim().equals("1")) { //$NON-NLS-1$ //$NON-NLS-2$
|
||||
isDynamic = true;
|
||||
} else if (var.equals("has_more") && str.trim().equals("1")) { //$NON-NLS-1$ //$NON-NLS-2$
|
||||
hasMore = true;
|
||||
} else if (var.equals("displayhint")) { //$NON-NLS-1$
|
||||
displayHint = new MIDisplayHint(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2009 QNX Software Systems and others.
|
||||
* Copyright (c) 2000, 2010 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
|
||||
|
@ -7,9 +7,11 @@
|
|||
*
|
||||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.mi.service.command.output;
|
||||
|
||||
|
||||
/**
|
||||
* GDB/MI var-update.
|
||||
*/
|
||||
|
@ -19,7 +21,12 @@ public class MIVarChange {
|
|||
String value;
|
||||
boolean inScope;
|
||||
boolean changed;
|
||||
|
||||
private boolean isDynamic = false;
|
||||
private int newNumChildren = -1;
|
||||
private boolean hasMore = false;
|
||||
private MIVar[] newChildren;
|
||||
private MIDisplayHint displayHint = MIDisplayHint.NONE;
|
||||
|
||||
public MIVarChange(String n) {
|
||||
name = n;
|
||||
}
|
||||
|
@ -40,6 +47,64 @@ public class MIVarChange {
|
|||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether the associated variable's value and children are provided
|
||||
* by a pretty printer.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public boolean isDynamic() {
|
||||
return isDynamic;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether the number of children changed since the last update.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public boolean numChildrenChanged() {
|
||||
return (newNumChildren != -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only call if {@link #numChildrenChanged()} returns true.
|
||||
*
|
||||
* @return The new number of children the associated varobj now has already fetched.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public int getNewNumChildren() {
|
||||
assert(newNumChildren != -1);
|
||||
return newNumChildren;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether there more children available than {@link #getNewNumChildren()}.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public boolean hasMore() {
|
||||
return hasMore;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The children added within the current update range.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public MIVar[] getNewChildren() {
|
||||
return newChildren;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The new display hint
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public MIDisplayHint getDisplayHint() {
|
||||
return displayHint;
|
||||
}
|
||||
|
||||
public void setValue(String v) {
|
||||
value = v;
|
||||
}
|
||||
|
@ -51,4 +116,41 @@ public class MIVarChange {
|
|||
public void setChanged(boolean c) {
|
||||
changed = c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
public void setDynamic(boolean isDynamic) {
|
||||
this.isDynamic = isDynamic;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
public void setNewNumChildren(int newNumChildren) {
|
||||
this.newNumChildren = newNumChildren;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
public void setHasMore(boolean hasMore) {
|
||||
this.hasMore = hasMore;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.0
|
||||
*/
|
||||
public void setNewChildren(MIVar[] newChildren) {
|
||||
this.newChildren = newChildren;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param hint
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public void setDisplayHint(MIDisplayHint hint) {
|
||||
displayHint = hint;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2009 QNX Software Systems and others.
|
||||
* Copyright (c) 2000, 2010 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
|
||||
|
@ -8,10 +8,12 @@
|
|||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
* Wind River Systems - Modified for new DSF Reference Implementation
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.dsf.mi.service.command.output;
|
||||
|
||||
|
||||
/**
|
||||
* GDB/MI var-create.
|
||||
* -var-create "-" * a
|
||||
|
@ -28,7 +30,10 @@ public class MIVarCreateInfo extends MIInfo {
|
|||
String type = ""; //$NON-NLS-1$
|
||||
MIVar child;
|
||||
String value = null;
|
||||
|
||||
private boolean isDynamic = false;
|
||||
private boolean hasMore = false;
|
||||
private MIDisplayHint displayHint = MIDisplayHint.NONE;
|
||||
|
||||
public MIVarCreateInfo(MIOutput record) {
|
||||
super(record);
|
||||
if (isDone()) {
|
||||
|
@ -55,6 +60,12 @@ public class MIVarCreateInfo extends MIInfo {
|
|||
type = str;
|
||||
} else if (var.equals("value")) { //$NON-NLS-1$
|
||||
value = str;
|
||||
} else if (var.equals("dynamic") && str.trim().equals("1")) { //$NON-NLS-1$ //$NON-NLS-2$
|
||||
isDynamic = true;
|
||||
} else if (var.equals("has_more") && str.trim().equals("1")) { //$NON-NLS-1$ //$NON-NLS-2$
|
||||
hasMore = true;
|
||||
} else if (var.equals("displayhint")) { //$NON-NLS-1$
|
||||
displayHint = new MIDisplayHint(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -66,11 +77,39 @@ public class MIVarCreateInfo extends MIInfo {
|
|||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether the created variable's value and children are provided
|
||||
* by a pretty printer.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public boolean isDynamic() {
|
||||
return isDynamic;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The number of children. If {@link #isDynamic()} returns true,
|
||||
* the returned value only reflects the number of children currently
|
||||
* fetched by gdb. Check {@link #hasMore()} in order to find out
|
||||
* whether the are more children.
|
||||
*/
|
||||
public int getNumChildren()
|
||||
{
|
||||
return numChild;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return For dynamic varobjs ({@link #isDynamic() returns true} this
|
||||
* method returns whether there are children in addition to the
|
||||
* currently fetched, i.e. whether there are more children than
|
||||
* {@link #getNumChildren()} returns.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public boolean hasMore() {
|
||||
return hasMore;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
|
@ -80,10 +119,20 @@ public class MIVarCreateInfo extends MIInfo {
|
|||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether the underlying value conceptually represents a string,
|
||||
* array, or map.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public MIDisplayHint getDisplayHint() {
|
||||
return displayHint;
|
||||
}
|
||||
|
||||
public MIVar getMIVar() {
|
||||
if (child == null) {
|
||||
child = new MIVar(name, numChild, type);
|
||||
child = new MIVar(name, isDynamic, numChild, hasMore, type, displayHint);
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2009 QNX Software Systems and others.
|
||||
* Copyright (c) 2000, 2010 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
|
||||
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.dsf.mi.service.command.output;
|
||||
|
@ -14,6 +15,9 @@ package org.eclipse.cdt.dsf.mi.service.command.output;
|
|||
|
||||
/**
|
||||
* GDB/MI var-info-num-children.
|
||||
*
|
||||
* For dynamic variable objects, only the number children currently fetched
|
||||
* by gdb is returned.
|
||||
*/
|
||||
public class MIVarInfoNumChildrenInfo extends MIInfo {
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2009 QNX Software Systems and others.
|
||||
* Copyright (c) 2000, 2010 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
|
||||
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.mi.service.command.output;
|
||||
|
||||
|
@ -23,7 +24,8 @@ public class MIVarListChildrenInfo extends MIInfo {
|
|||
|
||||
MIVar[] children;
|
||||
int numchild;
|
||||
|
||||
private boolean hasMore = false;
|
||||
|
||||
public MIVarListChildrenInfo(MIOutput record) {
|
||||
super(record);
|
||||
List<MIVar> aList = new ArrayList<MIVar>();
|
||||
|
@ -46,7 +48,14 @@ public class MIVarListChildrenInfo extends MIInfo {
|
|||
}
|
||||
} else if (var.equals("children")) { //$NON-NLS-1$
|
||||
parseChildren(value, aList);
|
||||
}
|
||||
} else if (var.equals("has_more")) { //$NON-NLS-1$
|
||||
if (value instanceof MIConst) {
|
||||
String str = ((MIConst) value).getString();
|
||||
if (str.trim().equals("1")) { //$NON-NLS-1$
|
||||
hasMore = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -57,6 +66,15 @@ public class MIVarListChildrenInfo extends MIInfo {
|
|||
return children;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether the are more children to fetch.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public boolean hasMore() {
|
||||
return hasMore;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some gdb MacOSX do not return a MITuple so we have
|
||||
* to check for different format.
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.mi.service.command.output;
|
||||
|
||||
|
@ -98,7 +99,45 @@ public class MIVarUpdateInfo extends MIInfo {
|
|||
if (change != null) {
|
||||
change.setChanged("true".equals(str)); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
} else if (var.equals("new_num_children")) { //$NON-NLS-1$
|
||||
if (change != null) {
|
||||
try {
|
||||
change.setNewNumChildren(Integer.parseInt(str.trim()));
|
||||
} catch (NumberFormatException e) {
|
||||
change.setNewNumChildren(0);
|
||||
}
|
||||
}
|
||||
} else if (var.equals("dynamic")) { //$NON-NLS-1$
|
||||
if (change != null) {
|
||||
change.setDynamic(str.trim().equals("1")); //$NON-NLS-1$
|
||||
}
|
||||
} else if (var.equals("has_more")) { //$NON-NLS-1$
|
||||
if (change != null) {
|
||||
change.setHasMore(str.trim().equals("1")); //$NON-NLS-1$
|
||||
}
|
||||
} else if (var.equals("new_children")) { //$NON-NLS-1$
|
||||
if (change != null) {
|
||||
List<MIVar> newChildren = new ArrayList<MIVar>();
|
||||
parseNewChildren(value, newChildren);
|
||||
change.setNewChildren(newChildren.toArray(new MIVar[newChildren.size()]));
|
||||
}
|
||||
} else if (var.equals("displayhint")) { //$NON-NLS-1$
|
||||
if (change != null) {
|
||||
change.setDisplayHint(new MIDisplayHint(str));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseNewChildren(MIValue value, List<MIVar> aList) {
|
||||
if (value instanceof MIList) {
|
||||
MIValue[] children = ((MIList)value).getMIValues();
|
||||
|
||||
for (MIValue child : children) {
|
||||
if (child instanceof MITuple) {
|
||||
aList.add(new MIVar((MITuple)child));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue