Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 298883 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/cdt/dsf/gdb/launching/GdbLaunchDelegate.java (-6 / +15 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2008, 2009  QNX Software Systems and others.
2
 * Copyright (c) 2010 QNX Software Systems and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 9-14 Link Here
9
 * QNX Software Systems   - Initial API and implementation
9
 * QNX Software Systems   - Initial API and implementation
10
 * Windriver and Ericsson - Updated for DSF
10
 * Windriver and Ericsson - Updated for DSF
11
 * IBM Corporation 
11
 * IBM Corporation 
12
 * Ericsson               - Added support for Mac OS
12
 *******************************************************************************/
13
 *******************************************************************************/
13
package org.eclipse.cdt.dsf.gdb.launching; 
14
package org.eclipse.cdt.dsf.gdb.launching; 
14
15
Lines 30-35 Link Here
30
import org.eclipse.cdt.dsf.gdb.service.GdbDebugServicesFactory;
31
import org.eclipse.cdt.dsf.gdb.service.GdbDebugServicesFactory;
31
import org.eclipse.cdt.dsf.gdb.service.GdbDebugServicesFactoryNS;
32
import org.eclipse.cdt.dsf.gdb.service.GdbDebugServicesFactoryNS;
32
import org.eclipse.cdt.dsf.gdb.service.SessionType;
33
import org.eclipse.cdt.dsf.gdb.service.SessionType;
34
import org.eclipse.cdt.dsf.gdb.service.macos.MacOSGdbDebugServicesFactory;
33
import org.eclipse.cdt.dsf.service.DsfSession;
35
import org.eclipse.cdt.dsf.service.DsfSession;
34
import org.eclipse.core.resources.IMarker;
36
import org.eclipse.core.resources.IMarker;
35
import org.eclipse.core.resources.IProject;
37
import org.eclipse.core.resources.IProject;
Lines 382-387 Link Here
382
	}
384
	}
383
	
385
	
384
	private boolean isNonStopSupported(String version) {
386
	private boolean isNonStopSupported(String version) {
387
		if (version.contains(LaunchUtils.MACOS_GDB_PREFIX)) {
388
			// Mac OS's GDB does not support Non-Stop
389
			return false;
390
		}
391
		
385
		if (NON_STOP_FIRST_VERSION.compareTo(version) <= 0) {
392
		if (NON_STOP_FIRST_VERSION.compareTo(version) <= 0) {
386
			return true;
393
			return true;
387
		}
394
		}
Lines 394-404 Link Here
394
		if (isNonStopSession && isNonStopSupported(version)) {
401
		if (isNonStopSession && isNonStopSupported(version)) {
395
			return new GdbDebugServicesFactoryNS(version);
402
			return new GdbDebugServicesFactoryNS(version);
396
		}
403
		}
397
404
		
398
		if (version.startsWith("6.6") ||  //$NON-NLS-1$
405
		if (version.contains(LaunchUtils.MACOS_GDB_PREFIX)) {
399
			version.startsWith("6.7") ||  //$NON-NLS-1$
406
			// The version string at this point should look like
400
			version.startsWith("6.8")) {  //$NON-NLS-1$
407
			// 6.3.50APPLE1346, we extract the gdb version and apple version
401
			return new GdbDebugServicesFactory(version);
408
			String versions [] = version.split(LaunchUtils.MACOS_GDB_PREFIX);
409
			if(versions.length == 2)
410
				return new MacOSGdbDebugServicesFactory(versions[0], versions[1]);
402
		}
411
		}
403
412
404
		return new GdbDebugServicesFactory(version);
413
		return new GdbDebugServicesFactory(version);
(-)src/org/eclipse/cdt/dsf/gdb/launching/LaunchUtils.java (-2 / +29 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2008 Ericsson and others.
2
 * Copyright (c) 2010 Ericsson and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 7-12 Link Here
7
 *
7
 *
8
 * Contributors:
8
 * Contributors:
9
 * Ericsson   - Initial API and implementation
9
 * Ericsson   - Initial API and implementation
10
 * Ericsson   - Added support for Mac OS
10
 *******************************************************************************/
11
 *******************************************************************************/
11
package org.eclipse.cdt.dsf.gdb.launching;
12
package org.eclipse.cdt.dsf.gdb.launching;
12
13
Lines 43-48 Link Here
43
44
44
public class LaunchUtils {
45
public class LaunchUtils {
45
46
47
	/**
48
	 * A prefix that we use to indicate that a GDB version is for MAC OS
49
	 * @since 2.1
50
	 */
51
	public static final String MACOS_GDB_PREFIX = "APPLE"; //$NON-NLS-1$
52
	
46
   	/**
53
   	/**
47
	 * Verify the following things about the project:
54
	 * Verify the following things about the project:
48
	 * - is a valid project name given
55
	 * - is a valid project name given
Lines 212-218 Link Here
212
     */
219
     */
213
	public static String getGDBVersionFromText(String versionOutput) {
220
	public static String getGDBVersionFromText(String versionOutput) {
214
        String version = "";//$NON-NLS-1$
221
        String version = "";//$NON-NLS-1$
215
        
222
        		
216
		// These are the GDB version patterns I have seen up to now
223
		// These are the GDB version patterns I have seen up to now
217
		// The pattern works for all of them extracting the version of 6.8.50.20080730
224
		// The pattern works for all of them extracting the version of 6.8.50.20080730
218
		// GNU gdb 6.8.50.20080730
225
		// GNU gdb 6.8.50.20080730
Lines 230-235 Link Here
230
				version = "6.8"; //$NON-NLS-1$
237
				version = "6.8"; //$NON-NLS-1$
231
			}
238
			}
232
		}
239
		}
240
		
241
        // Look for the case of Apple's GDB, since the version must be handled differently
242
        // The format is:
243
        // GNU gdb 6.3.50-20050815 (Apple version gdb-696) (Sat Oct 20 18:20:28 GMT 2007)
244
        // GNU gdb 6.3.50-20050815 (Apple version gdb-966) (Tue Mar 10 02:43:13 UTC 2009)
245
        // GNU gdb 6.3.50-20050815 (Apple version gdb-1346) (Fri Sep 18 20:40:51 UTC 2009)
246
        // It seems the version that changes is the "Apple version" but we still use both. 
247
		// The Mac OS prefix and version are appended to the normal version so the 
248
		// returned string has this format: 6.3.50APPLE1346. The normal version and the 
249
		// Apple version are extracted later and passed to the MacOS services factory.
250
        if (versionOutput.toLowerCase().indexOf("apple") != -1) {  //$NON-NLS-1$
251
        	// Add a prefix to indicate we are dealing with an Apple GDB
252
        	version += MACOS_GDB_PREFIX;
253
    		Pattern aPattern = Pattern.compile(" \\(Apple version gdb-(\\d*)\\)",  Pattern.MULTILINE); //$NON-NLS-1$
254
255
    		Matcher aMatcher = aPattern.matcher(versionOutput);
256
    		if (aMatcher.find()) {
257
    			version += aMatcher.group(1);
258
    		}
259
        }
233
260
234
        return version;
261
        return version;
235
	}
262
	}
(-)src/org/eclipse/cdt/dsf/gdb/service/macos/MacOSGDBExpressions.java (+32 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 Wind River Systems and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     Wind River Systems - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.cdt.dsf.gdb.service.macos;
12
13
import org.eclipse.cdt.dsf.mi.service.MIExpressions;
14
import org.eclipse.cdt.dsf.mi.service.MIVariableManager;
15
import org.eclipse.cdt.dsf.service.DsfSession;
16
17
/**
18
 * Specific ExpressionService for MacOS
19
 * 
20
 * @since 2.1
21
 */
22
public class MacOSGDBExpressions extends MIExpressions {
23
24
    public MacOSGDBExpressions(DsfSession session) {
25
        super(session);
26
    }
27
28
    @Override
29
    protected MIVariableManager createMIVariableManager() {
30
        return new MacOSGDBVariableManager(getSession(), getServicesTracker());
31
    }
32
}
(-)src/org/eclipse/cdt/dsf/gdb/service/macos/MacOSGDBVariableManager.java (+136 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 Wind River Systems and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     Wind River Systems - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.cdt.dsf.gdb.service.macos;
12
13
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
14
import org.eclipse.cdt.dsf.mi.service.MIVariableManager;
15
import org.eclipse.cdt.dsf.mi.service.command.commands.macos.MacOSMIVarUpdate;
16
import org.eclipse.cdt.dsf.mi.service.command.output.MIVarChange;
17
import org.eclipse.cdt.dsf.mi.service.command.output.macos.MacOSMIVarUpdateInfo;
18
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
19
import org.eclipse.cdt.dsf.service.DsfSession;
20
21
/**
22
 * Specific VariableManager for MacOS
23
 *   
24
 * @since 2.1
25
 */
26
public class MacOSGDBVariableManager extends MIVariableManager {
27
28
    public MacOSGDBVariableManager(DsfSession session, DsfServicesTracker tracker) {
29
        super(session, tracker);
30
    }
31
32
    @Override
33
    protected MIRootVariableObject createRootVariableObject(VariableObjectId id) {
34
    	return new MacOSGDBRootVariableObject(id);
35
    }
36
    
37
	private class MacOSGDBRootVariableObject extends MIRootVariableObject {
38
39
		public MacOSGDBRootVariableObject(VariableObjectId id) {
40
			super(id);
41
		}
42
43
		@Override
44
		public void update(final DataRequestMonitor<Boolean> rm) {
45
46
			if (isOutOfScope()) {
47
		    	rm.setData(false);
48
				rm.done();
49
			} else if (currentState != STATE_READY) {
50
				// Object is not fully created or is being updated
51
				// so add RequestMonitor to pending queue
52
				updatesPending.add(rm);
53
			} else if (getOutOfDate() == false) {
54
				rm.setData(false);
55
				rm.done();
56
			} else {
57
				// Object needs to be updated in the back-end
58
				currentState = STATE_UPDATING;
59
60
				// In GDB, var-update will only report a change if -var-evaluate-expression has
61
				// changed -- in the current format--.  This means that situations like
62
				// double z = 1.2;
63
				// z = 1.4;
64
				// Will not report a change if the format is anything else than natural.
65
				// This is because 1.2 and 1.4 are both printed as 1, 0x1, etc
66
				// Since we cache the values of every format, we must know if -any- format has
67
				// changed, not just the current one.
68
				// To solve this, we always do an update in the natural format; I am not aware
69
				// of any case where the natural format would stay the same, but another format
70
				// would change.  However, since a var-update update all children as well,
71
			    // we must make sure these children are also in the natural format
72
				// The simplest way to do this is that whenever we change the format
73
				// of a variable object, we immediately set it back to natural with a second
74
				// var-set-format command.  This is done in the getValue() method
75
				getCommandControl().queueCommand(
76
						new MacOSMIVarUpdate(getRootToUpdate().getControlDMContext(), getGdbName()),
77
						new DataRequestMonitor<MacOSMIVarUpdateInfo>(getSession().getExecutor(), rm) {
78
							@Override
79
							protected void handleCompleted() {
80
								currentState = STATE_READY;
81
								
82
								if (isSuccess()) {
83
									setOutOfDate(false);
84
85
									MIVarChange[] changes = getData().getMIVarChanges();
86
									if (changes.length > 0 && changes[0].isInScope() == false) {
87
										// Object is out-of-scope
88
										outOfScope = true;
89
										
90
										// We can delete this root in GDB right away.  This is safe, even
91
									 	// if the root has children, because they are also out-of-scope.
92
										// We -must- also remove this entry from our LRU.  If we don't
93
										// we can end-up with a race condition that create this object
94
										// twice, or have an infinite loop while never re-creating the object.
95
										// The can happen if we update a child first then we request 
96
										// the root later,
97
										getLRUCache().remove(getInternalId());
98
99
										rm.setData(true);
100
										rm.done();
101
									} else {
102
										// The root object is now up-to-date, we must parse the changes, if any.
103
										processChanges(changes);
104
105
										// We only mark this root as updated in our list if it is in-scope.
106
										// For out-of-scope object, we don't ever need to re-update them so
107
										// we don't need to add them to this list.
108
										rootVariableUpdated(MacOSGDBRootVariableObject.this);
109
110
										rm.setData(false);
111
										rm.done();
112
									}
113
114
									while (updatesPending.size() > 0) {
115
										DataRequestMonitor<Boolean> pendingRm = updatesPending.poll();
116
										pendingRm.setData(false);
117
										pendingRm.done();
118
									}
119
								} else {
120
									// We were not able to update for some reason
121
									rm.setData(false);
122
									rm.done();
123
124
									while (updatesPending.size() > 0) {
125
										DataRequestMonitor<Boolean> pendingRm = updatesPending.poll();
126
										pendingRm.setStatus(getStatus());
127
										pendingRm.done();
128
									}
129
								}
130
							}
131
						});
132
		    }
133
		}
134
	}
135
	
136
}
(-)src/org/eclipse/cdt/dsf/gdb/service/macos/MacOSGdbDebugServicesFactory.java (+35 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 Ericsson and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors:
9
 *     Marc-Andre Laperle - Added support for Mac OS (separate factory)
10
 *     Ericsson                  - Added a field for the specific Mac OS version scheme
11
 *******************************************************************************/
12
package org.eclipse.cdt.dsf.gdb.service.macos;
13
14
import org.eclipse.cdt.dsf.debug.service.IExpressions;
15
import org.eclipse.cdt.dsf.gdb.service.GdbDebugServicesFactory;
16
import org.eclipse.cdt.dsf.service.DsfSession;
17
18
public class MacOSGdbDebugServicesFactory extends GdbDebugServicesFactory {
19
20
	// Mac OS has it's own version of GDB, which does not follow the standard GDB version
21
	// We have to be careful not to compare that specific version number scheme with the 
22
	// FSF GDB version scheme.
23
	// Use this variable when needing to differentiate between different Mac OS GDBs
24
	private final String fAppleVersion;
25
26
	public MacOSGdbDebugServicesFactory(String version, String appleVersion) {
27
		super(version);
28
		fAppleVersion = appleVersion;
29
	}
30
31
	@Override
32
	protected IExpressions createExpressionService(DsfSession session) {
33
		return new MacOSGDBExpressions(session);
34
	}
35
}
(-)src/org/eclipse/cdt/dsf/mi/service/MIExpressions.java (-2 / +12 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2006, 2008 Wind River Systems and others.
2
 * Copyright (c) 2010 Wind River Systems and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 452-458 Link Here
452
        // to the back-end, through the MICommandControl service
452
        // to the back-end, through the MICommandControl service
453
		// It must be created after the ExpressionService is registered
453
		// It must be created after the ExpressionService is registered
454
		// since it will need to find it.
454
		// since it will need to find it.
455
        varManager = new MIVariableManager(getSession(), getServicesTracker());
455
        varManager = createMIVariableManager();
456
456
457
        // Create the meta command cache which will use the variable manager
457
        // Create the meta command cache which will use the variable manager
458
        // to actually send MI commands to the back-end
458
        // to actually send MI commands to the back-end
Lines 464-469 Link Here
464
	}
464
	}
465
465
466
	/**
466
	/**
467
	 * Creates the MI variable manager to be used by this expression service.
468
	 * Overriding classes may override to provide a custom services tracker. 
469
	 * 
470
	 * @since 2.1
471
	 */
472
	protected MIVariableManager createMIVariableManager() {
473
	    return new MIVariableManager(getSession(), getServicesTracker());
474
	}
475
	
476
	/**
467
	 * This method shuts down this service. It unregisters the service, stops
477
	 * This method shuts down this service. It unregisters the service, stops
468
	 * receiving service events, and calls the superclass shutdown() method to
478
	 * receiving service events, and calls the superclass shutdown() method to
469
	 * finish the shutdown process.
479
	 * finish the shutdown process.
(-)src/org/eclipse/cdt/dsf/mi/service/MIVariableManager.java (-18 / +82 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2008 Monta Vista and others.
2
 * Copyright (c) 2010 Monta Vista and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 697-703 Link Here
697
	        							}
697
	        							}
698
698
699
	        							if (childVar == null) {
699
	        							if (childVar == null) {
700
	        								childVar = new MIVariableObject(childId, MIVariableObject.this);
700
	        								childVar = createVariableObject(childId, MIVariableObject.this);
701
	        								childVar.setGdbName(child.getVarName());
701
	        								childVar.setGdbName(child.getVarName());
702
	        								childVar.setExpressionData(
702
	        								childVar.setExpressionData(
703
	        										childFullExpression,
703
	        										childFullExpression,
Lines 914-920 Link Here
914
		}
914
		}
915
	}
915
	}
916
	
916
	
917
	private class MIRootVariableObject extends MIVariableObject {
917
	/**
918
	 * Method to allow to override the MIVariableObject creation
919
	 * 
920
     * @since 2.1
921
     */
922
	protected MIVariableObject createVariableObject(VariableObjectId id, MIVariableObject parentObj) {
923
	    return new MIVariableObject(id, parentObj);
924
	}
925
	
926
	/**
927
     * @since 2.1
928
     */
929
	public class MIRootVariableObject extends MIVariableObject {
918
930
919
		// Only root variables go through the GDB creation process
931
		// Only root variables go through the GDB creation process
920
		protected static final int STATE_NOT_CREATED = 10;
932
		protected static final int STATE_NOT_CREATED = 10;
Lines 925-931 Link Here
925
		// will have the same control context
937
		// will have the same control context
926
	    private ICommandControlDMContext fControlContext = null;
938
	    private ICommandControlDMContext fControlContext = null;
927
	    
939
	    
928
		private boolean outOfDate = false;
940
		private boolean fOutOfDate = false;
929
		
941
		
930
	    // Modifiable descendants are any variable object that is a descendant or itself for
942
	    // Modifiable descendants are any variable object that is a descendant or itself for
931
	    // which the value can change.
943
	    // which the value can change.
Lines 940-947 Link Here
940
		public ICommandControlDMContext getControlDMContext() { return fControlContext; }
952
		public ICommandControlDMContext getControlDMContext() { return fControlContext; }
941
953
942
		public boolean isUpdating() { return currentState == STATE_UPDATING; }
954
		public boolean isUpdating() { return currentState == STATE_UPDATING; }
943
955
        
944
		public void markAsOutOfDate() { outOfDate = true; }
956
		public void setOutOfDate(boolean outOfDate) { fOutOfDate = outOfDate; }
957
		
958
		public boolean getOutOfDate() { return fOutOfDate; }
945
		
959
		
946
		// Remember that we must add ourself as a modifiable descendant if our value can change
960
		// Remember that we must add ourself as a modifiable descendant if our value can change
947
		public void addModifiableDescendant(String gdbName, MIVariableObject descendant) {
961
		public void addModifiableDescendant(String gdbName, MIVariableObject descendant) {
Lines 1033-1039 Link Here
1033
				// Object is not fully created or is being updated
1047
				// Object is not fully created or is being updated
1034
				// so add RequestMonitor to pending queue
1048
				// so add RequestMonitor to pending queue
1035
				updatesPending.add(rm);
1049
				updatesPending.add(rm);
1036
			} else if (outOfDate == false) {
1050
			} else if (getOutOfDate() == false) {
1037
				rm.setData(false);
1051
				rm.setData(false);
1038
				rm.done();
1052
				rm.done();
1039
			} else {
1053
			} else {
Lines 1063-1069 Link Here
1063
								currentState = STATE_READY;
1077
								currentState = STATE_READY;
1064
								
1078
								
1065
								if (isSuccess()) {
1079
								if (isSuccess()) {
1066
									outOfDate = false;
1080
									setOutOfDate(false);
1067
1081
1068
									MIVarChange[] changes = getData().getMIVarChanges();
1082
									MIVarChange[] changes = getData().getMIVarChanges();
1069
									if (changes.length > 0 && changes[0].isInScope() == false) {
1083
									if (changes.length > 0 && changes[0].isInScope() == false) {
Lines 1088-1094 Link Here
1088
										// We only mark this root as updated in our list if it is in-scope.
1102
										// We only mark this root as updated in our list if it is in-scope.
1089
										// For out-of-scope object, we don't ever need to re-update them so
1103
										// For out-of-scope object, we don't ever need to re-update them so
1090
										// we don't need to add them to this list.
1104
										// we don't need to add them to this list.
1091
										updatedRootList.add(MIRootVariableObject.this);
1105
										rootVariableUpdated(MIRootVariableObject.this);
1092
1106
1093
										rm.setData(false);
1107
										rm.setData(false);
1094
										rm.done();
1108
										rm.done();
Lines 1138-1146 Link Here
1138
		    } else {
1152
		    } else {
1139
		        // Variable was never created or was already deleted, no need to do anything.
1153
		        // Variable was never created or was already deleted, no need to do anything.
1140
		    }
1154
		    }
1141
		}		
1155
		}
1142
		
1156
	}
1143
1157
	
1158
    /**
1159
 	 * Method to allow to override the MIRootVariableObject creation.
1160
	 *
1161
     * @since 2.1
1162
     */
1163
	protected MIRootVariableObject createRootVariableObject(VariableObjectId id) {
1164
	    return new MIRootVariableObject(id);
1144
	}
1165
	}
1145
	
1166
	
1146
	/**
1167
	/**
Lines 1153-1160 Link Here
1153
	 *     
1174
	 *     
1154
	 * Note that if no frameContext is specified (only Execution, or even only Container), which can
1175
	 * Note that if no frameContext is specified (only Execution, or even only Container), which can
1155
	 * characterize a global variable for example, we will only use the available information.
1176
	 * characterize a global variable for example, we will only use the available information.
1177
	 * 
1178
	 * @since 2.1
1156
	 */
1179
	 */
1157
	private class VariableObjectId {
1180
	public class VariableObjectId {
1158
		// We don't use the expression context because it is not safe to compare them
1181
		// We don't use the expression context because it is not safe to compare them
1159
		// See bug 187718.  So we store the expression itself, and it's parent execution context.
1182
		// See bug 187718.  So we store the expression itself, and it's parent execution context.
1160
		String fExpression = null;
1183
		String fExpression = null;
Lines 1163-1168 Link Here
1163
        // the same frame will have a different level based on the current depth of the stack 
1186
        // the same frame will have a different level based on the current depth of the stack 
1164
		Integer fFrameId = null;
1187
		Integer fFrameId = null;
1165
		
1188
		
1189
		public VariableObjectId() {
1190
		}
1191
		
1166
		@Override
1192
		@Override
1167
		public boolean equals(Object other) {
1193
		public boolean equals(Object other) {
1168
			if (other instanceof VariableObjectId) {
1194
			if (other instanceof VariableObjectId) {
Lines 1220-1225 Link Here
1220
		}
1246
		}
1221
	}
1247
	}
1222
	
1248
	
1249
    /**
1250
 	 * Method to allow to override the VariableObjectId creation.
1251
	 *
1252
     * @since 2.1
1253
     */
1254
	protected VariableObjectId createVariableObjectId() {
1255
	    return new VariableObjectId();
1256
	}
1257
1258
	
1223
	/**
1259
	/**
1224
	 * This is the real work horse of managing our objects. Not only must every
1260
	 * This is the real work horse of managing our objects. Not only must every
1225
	 * value be unique to get inserted, this also creates an LRU (least recently
1261
	 * value be unique to get inserted, this also creates an LRU (least recently
Lines 1338-1343 Link Here
1338
    	fSession.removeServiceEventListener(this);
1374
    	fSession.removeServiceEventListener(this);
1339
	}
1375
	}
1340
1376
1377
    /**
1378
     * @since 2.1
1379
     */
1380
	protected DsfSession getSession() {
1381
	    return fSession;
1382
	}
1383
	
1384
	/**
1385
     * @since 2.1
1386
     */
1387
	protected ICommandControl getCommandControl() {
1388
	    return fCommandControl;
1389
	}
1390
	
1391
    /**
1392
     * @since 2.1
1393
     */
1394
	protected void rootVariableUpdated(MIRootVariableObject rootObj) {
1395
	    updatedRootList.add(rootObj);
1396
	}
1397
	
1398
    /**
1399
     * @since 2.1
1400
     */
1401
	protected Map<VariableObjectId, MIVariableObject> getLRUCache() {
1402
		return lruVariableList;
1403
	}
1404
	
1341
	/** 
1405
	/** 
1342
	 * This method returns a variable object based on the specified
1406
	 * This method returns a variable object based on the specified
1343
	 * ExpressionDMC, creating it in GDB if it was not created already.
1407
	 * ExpressionDMC, creating it in GDB if it was not created already.
Lines 1354-1360 Link Here
1354
                             final DataRequestMonitor<MIVariableObject> rm) {
1418
                             final DataRequestMonitor<MIVariableObject> rm) {
1355
		// Generate an id for this expression so that we can determine if we already
1419
		// Generate an id for this expression so that we can determine if we already
1356
		// have a variable object tracking it.  If we don't we'll need to create one.
1420
		// have a variable object tracking it.  If we don't we'll need to create one.
1357
		final VariableObjectId id = new VariableObjectId();
1421
		final VariableObjectId id = createVariableObjectId();
1358
		id.generateId(
1422
		id.generateId(
1359
				exprCtx,
1423
				exprCtx,
1360
				new RequestMonitor(fSession.getExecutor(), rm) {
1424
				new RequestMonitor(fSession.getExecutor(), rm) {
Lines 1431-1437 Link Here
1431
1495
1432
		// Variable objects that are created directly like this, are considered ROOT variable objects
1496
		// Variable objects that are created directly like this, are considered ROOT variable objects
1433
		// in comparison to variable objects that are children of other variable objects.
1497
		// in comparison to variable objects that are children of other variable objects.
1434
		final MIRootVariableObject newVarObj = new MIRootVariableObject(id);
1498
		final MIRootVariableObject newVarObj = createRootVariableObject(id);
1435
		
1499
		
1436
		// We must put this object in our map right away, in case it is 
1500
		// We must put this object in our map right away, in case it is 
1437
		// requested again, before it completes its creation.
1501
		// requested again, before it completes its creation.
Lines 1443-1449 Link Here
1443
			protected void handleCompleted() {
1507
			protected void handleCompleted() {
1444
				if (isSuccess()) {
1508
				if (isSuccess()) {
1445
					// Also store the object as a varObj that is up-to-date
1509
					// Also store the object as a varObj that is up-to-date
1446
					updatedRootList.add(newVarObj);
1510
    				rootVariableUpdated(newVarObj);	
1447
					// VarObj can now be used by others
1511
					// VarObj can now be used by others
1448
					newVarObj.creationCompleted(true);
1512
					newVarObj.creationCompleted(true);
1449
1513
Lines 1625-1631 Link Here
1625
    					}
1689
    					}
1626
    				});
1690
    				});
1627
    	
1691
    	
1628
    	} else if (command instanceof MIDataEvaluateExpression) {
1692
    	} else if (command instanceof MIDataEvaluateExpression<?>) {
1629
    		// This does not use the variable objects but sends the command directly to the back-end
1693
    		// This does not use the variable objects but sends the command directly to the back-end
1630
			fCommandControl.queueCommand(command, rm);
1694
			fCommandControl.queueCommand(command, rm);
1631
    	} else {
1695
    	} else {
Lines 1684-1690 Link Here
1684
    public void markAllOutOfDate() {
1748
    public void markAllOutOfDate() {
1685
    	MIRootVariableObject root;
1749
    	MIRootVariableObject root;
1686
    	while ((root = updatedRootList.poll()) != null) {
1750
    	while ((root = updatedRootList.poll()) != null) {
1687
    		root.markAsOutOfDate();
1751
    		root.setOutOfDate(true);
1688
    	}       
1752
    	}       
1689
    }
1753
    }
1690
1754
(-)src/org/eclipse/cdt/dsf/mi/service/command/commands/macos/MacOSMIVarUpdate.java (+49 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 QNX Software Systems and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     QNX Software Systems - Initial API and implementation
10
 *     Wind River Systems   - Modified for new DSF Reference Implementation
11
 *     Ericsson				- Modified for handling of frame contexts
12
 *******************************************************************************/
13
14
package org.eclipse.cdt.dsf.mi.service.command.commands.macos;
15
16
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
17
import org.eclipse.cdt.dsf.mi.service.command.commands.MICommand;
18
import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput;
19
import org.eclipse.cdt.dsf.mi.service.command.output.macos.MacOSMIVarUpdateInfo;
20
21
/**
22
 * 
23
 *     -var-update [print-values] {NAME | "*"}
24
 *
25
 *  Update the value of the variable object NAME by evaluating its
26
 *  expression after fetching all the new values from memory or registers.
27
 *  A `*' causes all existing variable objects to be updated.
28
 *  If print-values has a value for of 0 or --no-values, print only the names of the variables; 
29
 *  if print-values is 1 or --all-values, also print their values; 
30
 *  if it is 2 or --simple-values print the name and value for simple data types and just 
31
 *  the name for arrays, structures and unions. 
32
 *  
33
 *  It seems that for MacOS, we must use the full string for print-values, such as
34
 *  --all-values.
35
 * 
36
 * @since 2.1
37
 */
38
public class MacOSMIVarUpdate extends MICommand<MacOSMIVarUpdateInfo> {
39
40
	public MacOSMIVarUpdate(ICommandControlDMContext dmc, String name) {
41
		// Must use --all-values instead of 1 for Mac OS
42
		super(dmc, "-var-update", new String[] { "--all-values", name }); //$NON-NLS-1$//$NON-NLS-2$
43
	}
44
	
45
    @Override
46
    public MacOSMIVarUpdateInfo getResult(MIOutput out) {
47
        return new MacOSMIVarUpdateInfo(out);
48
    }
49
}
(-)src/org/eclipse/cdt/dsf/mi/service/command/output/macos/MacOSMIVarUpdateInfo.java (+123 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010 QNX Software Systems and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     QNX Software Systems - Initial API and implementation
10
 *     Ericsson             - Created version for Mac OS
11
 *******************************************************************************/
12
package org.eclipse.cdt.dsf.mi.service.command.output.macos;
13
14
import java.util.ArrayList;
15
import java.util.List;
16
17
import org.eclipse.cdt.dsf.mi.service.command.output.MIConst;
18
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
19
import org.eclipse.cdt.dsf.mi.service.command.output.MIList;
20
import org.eclipse.cdt.dsf.mi.service.command.output.MIOutput;
21
import org.eclipse.cdt.dsf.mi.service.command.output.MIResult;
22
import org.eclipse.cdt.dsf.mi.service.command.output.MIResultRecord;
23
import org.eclipse.cdt.dsf.mi.service.command.output.MITuple;
24
import org.eclipse.cdt.dsf.mi.service.command.output.MIValue;
25
import org.eclipse.cdt.dsf.mi.service.command.output.MIVarChange;
26
27
/**
28
 * GDB/MI var-update for Mac OS.
29
 * -var-update *
30
 * ^done,changelist=[varobj={name="var1",in_scope="true",type_changed="false"}],time={.....}
31
 * 
32
 * @since 2.1
33
 */
34
public class MacOSMIVarUpdateInfo extends MIInfo {
35
36
	MIVarChange[] changeList;
37
38
	public MacOSMIVarUpdateInfo(MIOutput record) {
39
		super(record);
40
        List<MIVarChange> aList = new ArrayList<MIVarChange>();
41
        if (isDone()) {
42
            MIOutput out = getMIOutput();
43
            MIResultRecord rr = out.getMIResultRecord();
44
            if (rr != null) {
45
                MIResult[] results =  rr.getMIResults();
46
                for (int i = 0; i < results.length; i++) {
47
                    String var = results[i].getVariable();
48
                    if (var.equals("changelist")) { //$NON-NLS-1$
49
                        MIValue value = results[i].getMIValue();
50
                        if (value instanceof MITuple) {
51
                            parseChangeList((MITuple)value, aList);
52
                        } else if (value instanceof MIList) {
53
                            parseChangeList((MIList)value, aList);
54
                        }
55
                    }
56
                }
57
            }
58
        }
59
        changeList = aList.toArray(new MIVarChange[aList.size()]);
60
	}
61
62
	public MIVarChange[] getMIVarChanges() {
63
		return changeList;
64
	}
65
66
	/**
67
	 * For MI2 the format is now a MIList.
68
	 * @param tuple
69
	 * @param aList
70
	 */
71
	void parseChangeList(MIList miList, List<MIVarChange> aList) {
72
		// The MIList in Apple gdb contains MIResults instead of MIValues. It looks like:
73
		// ^done,changelist=[varobj={name="var1",in_scope="true",type_changed="false"}],time={.....}
74
		// Bug 250037
75
		MIResult[] results = miList.getMIResults();
76
		for (int i = 0; i < results.length; i++) {
77
			String var = results[i].getVariable();
78
			if (var.equals("varobj")) { //$NON-NLS-1$
79
				MIValue value = results[i].getMIValue();
80
				if (value instanceof MITuple) {
81
					parseChangeList((MITuple)value, aList);
82
				} else if (value instanceof MIList) {
83
					parseChangeList((MIList)value, aList);
84
				}
85
			}
86
		}
87
	} 
88
	
89
	void parseChangeList(MITuple tuple, List<MIVarChange> aList) {
90
		MIResult[] results = tuple.getMIResults();
91
		MIVarChange change = null;
92
		for (int i = 0; i < results.length; i++) {
93
			String var = results[i].getVariable();
94
			MIValue value = results[i].getMIValue();
95
			if (value instanceof MITuple) {
96
				parseChangeList((MITuple)value, aList);
97
			}
98
			else
99
			{
100
				String str = ""; //$NON-NLS-1$
101
				if (value instanceof MIConst) {
102
					str = ((MIConst)value).getString();
103
				}
104
				if (var.equals("name")) { //$NON-NLS-1$
105
					change = new MIVarChange(str);
106
					aList.add(change);
107
				} else if (var.equals("value")) { //$NON-NLS-1$
108
					if (change != null) {
109
						change.setValue(str);
110
					}
111
				} else if (var.equals("in_scope")) { //$NON-NLS-1$
112
					if (change != null) {
113
						change.setInScope("true".equals(str)); //$NON-NLS-1$
114
					}
115
				} else if (var.equals("type_changed")) { //$NON-NLS-1$
116
					if (change != null) {
117
						change.setChanged("true".equals(str)); //$NON-NLS-1$
118
					}
119
				}				
120
			}
121
		}
122
	}
123
}

Return to bug 298883