~ubuntu-branches/debian/sid/eclipse-cdt/sid

« back to all changes in this revision

Viewing changes to results/plugins/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/model/CVariable.java

  • Committer: Package Import Robot
  • Author(s): Jakub Adam
  • Date: 2011-10-06 21:15:04 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20111006211504-8dutmljjih0zikfv
Tags: 8.0.1-1
* New upstream release.
* Split the JNI packages into a separate architecture dependent
  package and made eclipse-cdt architecture independent.
* Install JNI libraries into multiarch aware location
* Bumped Standards-Version to 3.9.2.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*******************************************************************************
2
 
 * Copyright (c) 2004, 2007 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
 
 *******************************************************************************/
11
 
package org.eclipse.cdt.debug.internal.core.model;
12
 
 
13
 
import com.ibm.icu.text.MessageFormat;
14
 
 
15
 
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
16
 
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
17
 
import org.eclipse.cdt.debug.core.ICDebugConstants;
18
 
import org.eclipse.cdt.debug.core.cdi.event.ICDIChangedEvent;
19
 
import org.eclipse.cdt.debug.core.cdi.event.ICDIEvent;
20
 
import org.eclipse.cdt.debug.core.cdi.event.ICDIEventListener;
21
 
import org.eclipse.cdt.debug.core.cdi.event.ICDIMemoryChangedEvent;
22
 
import org.eclipse.cdt.debug.core.cdi.event.ICDIResumedEvent;
23
 
import org.eclipse.cdt.debug.core.cdi.model.ICDIObject;
24
 
import org.eclipse.cdt.debug.core.cdi.model.ICDITarget;
25
 
import org.eclipse.cdt.debug.core.cdi.model.ICDITargetConfiguration;
26
 
import org.eclipse.cdt.debug.core.cdi.model.ICDITargetConfiguration2;
27
 
import org.eclipse.cdt.debug.core.cdi.model.ICDITargetConfiguration3;
28
 
import org.eclipse.cdt.debug.core.cdi.model.ICDIVariable;
29
 
import org.eclipse.cdt.debug.core.cdi.model.ICDIVariableDescriptor;
30
 
import org.eclipse.cdt.debug.core.model.CVariableFormat;
31
 
import org.eclipse.cdt.debug.core.model.ICDebugElementStatus;
32
 
import org.eclipse.cdt.debug.core.model.ICType;
33
 
import org.eclipse.cdt.debug.core.model.ICValue;
34
 
import org.eclipse.cdt.debug.internal.core.CSettingsManager;
35
 
import org.eclipse.core.runtime.CoreException;
36
 
import org.eclipse.debug.core.DebugEvent;
37
 
import org.eclipse.debug.core.DebugException;
38
 
import org.eclipse.debug.core.DebugPlugin;
39
 
import org.eclipse.debug.core.model.IValue;
40
 
 
41
 
/**
42
 
 * A thin wrapper over the CVariable for injection into the CDI event manager's
43
 
 * listener collection. We used to directly inject the CVariable, but that's
44
 
 * problematic since CVariable overrides the equals() method to base the
45
 
 * decision on the internal variable object. So if two CVariables were added to
46
 
 * the listener list for the same underlying value, trying to later remove one
47
 
 * of the listeners had a 50/50 chance of removing the wrong one.
48
 
 * 
49
 
 * How can you end up with two CVariables for the same internal variable on the
50
 
 * listener list? Easy. 
51
 
 * 1. View a register in the Registers view. 
52
 
 * 2. Create a custom register group that contains the same register. 
53
 
 * 3. Expand the custom register group 
54
 
 * 4. Remove the custom register group 
55
 
 * Step 4 removed the wrong CVariable from the listener list.
56
 
 * 
57
 
 */
58
 
class VariableEventListener implements ICDIEventListener {
59
 
        private CVariable fVar;
60
 
        public VariableEventListener(CVariable var) {
61
 
                fVar = var;
62
 
        }
63
 
        /* (non-Javadoc)
64
 
         * @see org.eclipse.cdt.debug.core.cdi.event.ICDIEventListener#handleDebugEvents(org.eclipse.cdt.debug.core.cdi.event.ICDIEvent[])
65
 
         */
66
 
        public void handleDebugEvents(ICDIEvent[] events) {
67
 
                fVar.handleDebugEvents(events);
68
 
        }
69
 
}
70
 
 
71
 
/**
72
 
 * Represents a variable in the CDI model.
73
 
 */
74
 
public abstract class CVariable extends AbstractCVariable implements ICDIEventListener {
75
 
 
76
 
        interface IInternalVariable {
77
 
                IInternalVariable createShadow( int start, int length ) throws DebugException;
78
 
                IInternalVariable createShadow( String type ) throws DebugException;
79
 
                CType getType() throws DebugException;
80
 
                String getQualifiedName() throws DebugException;
81
 
                ICValue getValue() throws DebugException;
82
 
                void setValue( String expression ) throws DebugException;
83
 
                boolean isChanged();
84
 
                void setChanged( boolean changed );
85
 
                void dispose( boolean destroy );
86
 
                boolean isSameDescriptor( ICDIVariableDescriptor desc );
87
 
                boolean isSameVariable( ICDIVariable cdiVar );
88
 
                void resetValue();
89
 
                boolean isEditable() throws DebugException;
90
 
                boolean isArgument();
91
 
                int sizeof();
92
 
                void invalidateValue();
93
 
                void preserve();
94
 
                
95
 
                // Note: the CDI object association can change; e.g., if a "Cast to Type"
96
 
                // or "Display as Array" is done on the element.
97
 
                ICDIObject getCdiObject();
98
 
        }
99
 
 
100
 
        /**
101
 
         * Whether this variable is currently enabled.
102
 
         */
103
 
        private boolean fIsEnabled = true;
104
 
 
105
 
        /**
106
 
         * The original internal variable.
107
 
         */
108
 
        private IInternalVariable fOriginal;
109
 
 
110
 
        /**
111
 
         * The shadow internal variable used for casting.
112
 
         */
113
 
        private IInternalVariable fShadow;
114
 
 
115
 
        /**
116
 
         * The name of this variable.
117
 
         */
118
 
        private String fName;
119
 
 
120
 
        /**
121
 
         * The current format of this variable.
122
 
         */
123
 
        private CVariableFormat fFormat = CVariableFormat.getFormat( CDebugCorePlugin.getDefault().getPluginPreferences().getInt( ICDebugConstants.PREF_DEFAULT_VARIABLE_FORMAT ) );
124
 
 
125
 
        /**
126
 
         * Whether this variable has been disposed.
127
 
         */
128
 
        private boolean fIsDisposed = false;
129
 
 
130
 
        /**
131
 
         * Thin wrapper for instertion into the CDI event manager's listener list
132
 
         */
133
 
        private VariableEventListener fEventListenerWrapper;
134
 
 
135
 
        /**
136
 
         * Constructor for CVariable.
137
 
         */
138
 
        protected CVariable( CDebugElement parent, ICDIVariableDescriptor cdiVariableObject ) {
139
 
                super( parent );
140
 
                fEventListenerWrapper = new VariableEventListener(this);
141
 
                if ( cdiVariableObject != null ) {
142
 
                        setName( cdiVariableObject.getName() );
143
 
                        createOriginal( cdiVariableObject );
144
 
                }
145
 
                fIsEnabled = ( parent instanceof AbstractCValue ) ? ((AbstractCValue)parent).getParentVariable().isEnabled() : !isBookkeepingEnabled();
146
 
                getCDISession().getEventManager().addEventListener( fEventListenerWrapper );
147
 
                if ( cdiVariableObject != null ) {
148
 
                        setInitialFormat();
149
 
                }
150
 
        }
151
 
 
152
 
        /**
153
 
         * Constructor for CVariable.
154
 
         */
155
 
        protected CVariable( CDebugElement parent, ICDIVariableDescriptor cdiVariableObject, String errorMessage ) {
156
 
                super( parent );
157
 
                fEventListenerWrapper = new VariableEventListener(this);
158
 
                if ( cdiVariableObject != null ) {
159
 
                        setName( cdiVariableObject.getName() );
160
 
                        createOriginal( cdiVariableObject );
161
 
                }
162
 
                fIsEnabled = !isBookkeepingEnabled();
163
 
                setStatus( ICDebugElementStatus.ERROR, MessageFormat.format( CoreModelMessages.getString( "CVariable.1" ), (Object[])new String[]{ errorMessage } ) ); //$NON-NLS-1$
164
 
                getCDISession().getEventManager().addEventListener( fEventListenerWrapper );
165
 
                if ( cdiVariableObject != null ) {
166
 
                        setInitialFormat();
167
 
                }               
168
 
        }
169
 
 
170
 
        /*
171
 
         * (non-Javadoc)
172
 
         * 
173
 
         * @see org.eclipse.cdt.debug.core.model.ICVariable#getType()
174
 
         */
175
 
        public ICType getType() throws DebugException {
176
 
                if ( isDisposed() )
177
 
                        return null;
178
 
                IInternalVariable iv = getCurrentInternalVariable();
179
 
                return ( iv != null ) ? iv.getType() : null;
180
 
        }
181
 
 
182
 
        /*
183
 
         * (non-Javadoc)
184
 
         * 
185
 
         * @see org.eclipse.cdt.debug.core.model.ICVariable#isEnabled()
186
 
         */
187
 
        public boolean isEnabled() {
188
 
                return fIsEnabled;
189
 
        }
190
 
 
191
 
        /*
192
 
         * (non-Javadoc)
193
 
         * 
194
 
         * @see org.eclipse.cdt.debug.core.model.ICVariable#setEnabled(boolean)
195
 
         */
196
 
        public void setEnabled( boolean enabled ) throws DebugException {
197
 
                // Debugger engines that use active variable objects will benefit
198
 
                // performance-wise if we dispose the internal variable when it's 
199
 
                // disabled by the user (it will automatically get lazily recreated if 
200
 
                // it's ever needed again). Engines using passive variables probably 
201
 
                // won't, so we can defer the dispose until we have no use for the 
202
 
                // variable altogether.
203
 
                boolean disposeVariable = true;
204
 
                ICDITargetConfiguration configuration = getParent().getCDITarget().getConfiguration();
205
 
                if (configuration instanceof ICDITargetConfiguration2) {
206
 
                        disposeVariable = !((ICDITargetConfiguration2)configuration).supportsPassiveVariableUpdate();
207
 
                }
208
 
                if (disposeVariable) {
209
 
                        IInternalVariable iv = getOriginal();
210
 
                        if ( iv != null )
211
 
                                iv.dispose( true );
212
 
                        iv = getShadow();
213
 
                        if ( iv != null )
214
 
                                iv.dispose( true );
215
 
                }
216
 
                fIsEnabled = enabled;
217
 
                fireChangeEvent( DebugEvent.STATE );
218
 
        }
219
 
 
220
 
        /*
221
 
         * (non-Javadoc)
222
 
         * 
223
 
         * @see org.eclipse.cdt.debug.core.model.ICVariable#canEnableDisable()
224
 
         */
225
 
        public boolean canEnableDisable() {
226
 
                return !( getParent() instanceof IValue );
227
 
        }
228
 
 
229
 
        /*
230
 
         * (non-Javadoc)
231
 
         * 
232
 
         * @see org.eclipse.cdt.debug.core.model.ICVariable#isArgument()
233
 
         */
234
 
        public boolean isArgument() {
235
 
                IInternalVariable iv = getOriginal();
236
 
                return ( iv != null ) ? iv.isArgument() : false;
237
 
        }
238
 
 
239
 
        /*
240
 
         * (non-Javadoc)
241
 
         * 
242
 
         * @see org.eclipse.debug.core.model.IVariable#getValue()
243
 
         */
244
 
        public IValue getValue() throws DebugException {
245
 
                if ( !isDisposed() && isEnabled() ) {
246
 
                        IInternalVariable iv = getCurrentInternalVariable();
247
 
                        if ( iv != null ) {
248
 
                                try {
249
 
                                        return iv.getValue();
250
 
                                }
251
 
                                catch( DebugException e ) {
252
 
                                        setStatus( ICDebugElementStatus.ERROR, e.getMessage() );
253
 
                                }
254
 
                        }
255
 
                }
256
 
                return CValueFactory.NULL_VALUE;
257
 
        }
258
 
 
259
 
        /*
260
 
         * (non-Javadoc)
261
 
         * 
262
 
         * @see org.eclipse.debug.core.model.IVariable#getName()
263
 
         */
264
 
        public String getName() throws DebugException {
265
 
                return fName;
266
 
        }
267
 
 
268
 
        /*
269
 
         * (non-Javadoc)
270
 
         * 
271
 
         * @see org.eclipse.debug.core.model.IVariable#getReferenceTypeName()
272
 
         */
273
 
        public String getReferenceTypeName() throws DebugException {
274
 
                ICType type = getType();
275
 
                return ( type != null ) ? type.getName() : ""; //$NON-NLS-1$
276
 
        }
277
 
 
278
 
        /*
279
 
         * (non-Javadoc)
280
 
         * 
281
 
         * @see org.eclipse.debug.core.model.IVariable#hasValueChanged()
282
 
         */
283
 
        public boolean hasValueChanged() throws DebugException {
284
 
                if ( isDisposed() )
285
 
                        return false;
286
 
                IInternalVariable iv = getCurrentInternalVariable(); 
287
 
                return ( iv != null ) ? iv.isChanged() : false;
288
 
        }
289
 
 
290
 
        /*
291
 
         * (non-Javadoc)
292
 
         * 
293
 
         * @see org.eclipse.cdt.debug.core.model.IFormatSupport#supportsFormatting()
294
 
         */
295
 
        public boolean supportsFormatting() {
296
 
                return true;
297
 
        }
298
 
 
299
 
        /*
300
 
         * (non-Javadoc)
301
 
         * 
302
 
         * @see org.eclipse.cdt.debug.core.model.IFormatSupport#getFormat()
303
 
         */
304
 
        public CVariableFormat getFormat() {
305
 
                return fFormat;
306
 
        }
307
 
 
308
 
        /*
309
 
         * (non-Javadoc)
310
 
         * 
311
 
         * @see org.eclipse.cdt.debug.core.model.IFormatSupport#changeFormat(org.eclipse.cdt.debug.core.model.CVariableFormat)
312
 
         */
313
 
        public void changeFormat( CVariableFormat format ) throws DebugException {
314
 
                setFormat( format );
315
 
                storeFormat( format );
316
 
                resetValue();
317
 
        }
318
 
 
319
 
        /*
320
 
         * (non-Javadoc)
321
 
         * Allow this operation only for the pointer types (???).
322
 
         * 
323
 
         * @see org.eclipse.cdt.debug.core.model.ICastToArray#canCastToArray()
324
 
         */
325
 
        public boolean canCastToArray() {
326
 
                ICType type;
327
 
                try {
328
 
                        type = getType();
329
 
                        return ( getOriginal() != null && isEnabled() && type != null && type.isPointer() );
330
 
                }
331
 
                catch( DebugException e ) {
332
 
                }
333
 
                return false;
334
 
        }
335
 
 
336
 
        /*
337
 
         * (non-Javadoc)
338
 
         * 
339
 
         * @see org.eclipse.cdt.debug.core.model.ICastToArray#castToArray(int, int)
340
 
         */
341
 
        public void castToArray( int startIndex, int length ) throws DebugException {
342
 
                IInternalVariable current = getCurrentInternalVariable();
343
 
                if ( current != null ) {
344
 
                        IInternalVariable newVar = current.createShadow( startIndex, length );
345
 
                        if ( getShadow() != null )
346
 
                                getShadow().dispose( true );
347
 
                        setShadow( newVar );
348
 
                        // If casting of variable to a type or array causes an error, the status 
349
 
                        // of the variable is set to "error" and it can't be reset by subsequent castings.
350
 
                        resetValue();
351
 
                        storeCastToArray( startIndex, length );
352
 
                }
353
 
        }
354
 
 
355
 
        /*
356
 
         * (non-Javadoc)
357
 
         * 
358
 
         * @see org.eclipse.debug.core.model.IValueModification#setValue(java.lang.String)
359
 
         */
360
 
        public void setValue( String expression ) throws DebugException {
361
 
                IInternalVariable iv = getCurrentInternalVariable();
362
 
                if ( iv != null ) {
363
 
                        String newExpression = processExpression( expression );
364
 
                        iv.setValue( newExpression );
365
 
                }
366
 
        }
367
 
 
368
 
        /*
369
 
         * (non-Javadoc)
370
 
         * 
371
 
         * @see org.eclipse.debug.core.model.IValueModification#setValue(org.eclipse.debug.core.model.IValue)
372
 
         */
373
 
        public void setValue( IValue value ) throws DebugException {
374
 
                notSupported( CoreModelMessages.getString( "CVariable.3" ) ); //$NON-NLS-1$
375
 
        }
376
 
 
377
 
        /*
378
 
         * (non-Javadoc)
379
 
         * 
380
 
         * @see org.eclipse.debug.core.model.IValueModification#supportsValueModification()
381
 
         */
382
 
        public boolean supportsValueModification() {
383
 
                try {
384
 
                        return fIsEnabled ? getCurrentInternalVariable().isEditable() : false;
385
 
                }
386
 
                catch( DebugException e ) {
387
 
                }
388
 
                return false;
389
 
        }
390
 
 
391
 
        /*
392
 
         * (non-Javadoc)
393
 
         * 
394
 
         * @see org.eclipse.debug.core.model.IValueModification#verifyValue(java.lang.String)
395
 
         */
396
 
        public boolean verifyValue( String expression ) throws DebugException {
397
 
                return true;
398
 
        }
399
 
 
400
 
        /*
401
 
         * (non-Javadoc)
402
 
         * 
403
 
         * @see org.eclipse.debug.core.model.IValueModification#verifyValue(org.eclipse.debug.core.model.IValue)
404
 
         */
405
 
        public boolean verifyValue( IValue value ) throws DebugException {
406
 
                return value.getDebugTarget().equals( getDebugTarget() );
407
 
        }
408
 
 
409
 
        /*
410
 
         * (non-Javadoc)
411
 
         * 
412
 
         * @see org.eclipse.cdt.debug.core.model.ICastToType#canCast()
413
 
         */
414
 
        public boolean canCast() {
415
 
                return ( getOriginal() != null && isEnabled() );
416
 
        }
417
 
 
418
 
        /*
419
 
         * (non-Javadoc)
420
 
         * 
421
 
         * @see org.eclipse.cdt.debug.core.model.ICastToType#getCurrentType()
422
 
         */
423
 
        public String getCurrentType() {
424
 
                String typeName = ""; //$NON-NLS-1$
425
 
                try {
426
 
                        typeName = getReferenceTypeName();
427
 
                }
428
 
                catch( DebugException e ) {
429
 
                }
430
 
                return typeName;
431
 
        }
432
 
 
433
 
        /*
434
 
         * (non-Javadoc)
435
 
         * 
436
 
         * @see org.eclipse.cdt.debug.core.model.ICastToType#cast(java.lang.String)
437
 
         */
438
 
        public void cast( String type ) throws DebugException {
439
 
                IInternalVariable current = getCurrentInternalVariable();
440
 
                if ( current != null ) {
441
 
                        IInternalVariable newVar = current.createShadow( type );
442
 
                        if ( getShadow() != null )
443
 
                                getShadow().dispose( true );
444
 
                        setShadow( newVar );
445
 
                        // If casting of variable to a type or array causes an error, the status 
446
 
                        // of the variable is set to "error" and it can't be reset by subsequent castings.
447
 
                        resetValue();
448
 
                        storeCast(type);
449
 
                }
450
 
        }
451
 
 
452
 
        /*
453
 
         * (non-Javadoc)
454
 
         * 
455
 
         * @see org.eclipse.cdt.debug.core.model.ICastToType#restoreOriginal()
456
 
         */
457
 
        public void restoreOriginal() throws DebugException {
458
 
                IInternalVariable oldVar = getShadow();
459
 
                setShadow( null );
460
 
                if ( oldVar != null )
461
 
                        oldVar.dispose( true );
462
 
                IInternalVariable iv = getOriginal();
463
 
                if ( iv != null )
464
 
                        iv.invalidateValue();
465
 
                // If casting of variable to a type or array causes an error, the status 
466
 
                // of the variable is set to "error" and it can't be reset by subsequent castings.
467
 
                resetValue();
468
 
                forgetCast();
469
 
                forgetCastToArray();
470
 
        }
471
 
 
472
 
        /*
473
 
         * (non-Javadoc)
474
 
         * 
475
 
         * @see org.eclipse.cdt.debug.core.model.ICastToType#isCasted()
476
 
         */
477
 
        public boolean isCasted() {
478
 
                return ( getShadow() != null );
479
 
        }
480
 
 
481
 
        /*
482
 
         * (non-Javadoc)
483
 
         * 
484
 
         * @see org.eclipse.cdt.debug.core.cdi.event.ICDIEventListener#handleDebugEvents(org.eclipse.cdt.debug.core.cdi.event.ICDIEvent[])
485
 
         */
486
 
        public void handleDebugEvents( ICDIEvent[] events ) {
487
 
                IInternalVariable iv = getCurrentInternalVariable();
488
 
                if ( iv == null )
489
 
                        return;
490
 
                for( int i = 0; i < events.length; i++ ) {
491
 
                        ICDIEvent event = events[i];
492
 
                        ICDIObject source = event.getSource();
493
 
                        if ( source == null )
494
 
                                continue;
495
 
                        ICDITarget target = source.getTarget();
496
 
                        if ( target.equals( getCDITarget() ) ) {
497
 
                                if ( event instanceof ICDIMemoryChangedEvent &&
498
 
                                                target.getConfiguration() instanceof ICDITargetConfiguration3 &&
499
 
                                                ((ICDITargetConfiguration3)target.getConfiguration()).needsVariablesUpdated(event)) {
500
 
                                        resetValue();
501
 
                                }
502
 
                                else if ( event instanceof ICDIChangedEvent ) {
503
 
                                        if ( source instanceof ICDIVariable && iv.isSameVariable( (ICDIVariable)source ) ) {
504
 
                                                handleChangedEvent( (ICDIChangedEvent)event );
505
 
                                        }
506
 
                                }
507
 
                                else if ( event instanceof ICDIResumedEvent ) {
508
 
                                        handleResumedEvent( (ICDIResumedEvent)event );
509
 
                                }
510
 
                        }
511
 
                }
512
 
        }
513
 
 
514
 
        private void handleResumedEvent( ICDIResumedEvent event ) {
515
 
                boolean changed = false;
516
 
                if ( hasErrors() ) {
517
 
                        resetStatus();
518
 
                        changed = true;
519
 
                        IInternalVariable iv = getCurrentInternalVariable();
520
 
                        if ( iv != null )
521
 
                                iv.invalidateValue();
522
 
                }
523
 
                if ( changed )
524
 
                        fireChangeEvent( DebugEvent.STATE );
525
 
        }
526
 
 
527
 
        private void handleChangedEvent( ICDIChangedEvent event ) {
528
 
                IInternalVariable iv = getCurrentInternalVariable();
529
 
                if ( iv != null ) {
530
 
                        iv.setChanged( true );
531
 
                        fireChangeEvent( DebugEvent.STATE );
532
 
                }
533
 
        }
534
 
 
535
 
        private IInternalVariable getCurrentInternalVariable() {
536
 
                if ( getShadow() != null )
537
 
                        return getShadow();
538
 
                return getOriginal();
539
 
        }
540
 
 
541
 
        private IInternalVariable getOriginal() {
542
 
                return fOriginal;
543
 
        }
544
 
 
545
 
        protected void setOriginal( IInternalVariable original ) {
546
 
                fOriginal = original;
547
 
        }
548
 
 
549
 
        private IInternalVariable getShadow() {
550
 
                return fShadow;
551
 
        }
552
 
 
553
 
        private void setShadow( IInternalVariable shadow ) {
554
 
                fShadow = shadow;
555
 
        }
556
 
 
557
 
        protected boolean isBookkeepingEnabled() {
558
 
                boolean result = false;
559
 
                try {
560
 
                        result = getLaunch().getLaunchConfiguration().getAttribute( ICDTLaunchConfigurationConstants.ATTR_DEBUGGER_ENABLE_VARIABLE_BOOKKEEPING, false );
561
 
                }
562
 
                catch( CoreException e ) {
563
 
                }
564
 
                return result;
565
 
        }
566
 
 
567
 
        abstract protected void createOriginal( ICDIVariableDescriptor vo );
568
 
 
569
 
        protected boolean hasErrors() {
570
 
                return !isOK();
571
 
        }
572
 
 
573
 
        /* (non-Javadoc)
574
 
         * @see org.eclipse.cdt.debug.internal.core.model.AbstractCVariable#setChanged(boolean)
575
 
         */
576
 
        @Override
577
 
    protected void setChanged( boolean changed ) {
578
 
                IInternalVariable iv = getCurrentInternalVariable();
579
 
                if ( iv != null ) {
580
 
                        iv.setChanged( changed );
581
 
                }
582
 
        }
583
 
 
584
 
        /* (non-Javadoc)
585
 
         * @see org.eclipse.cdt.debug.internal.core.model.AbstractCVariable#resetValue()
586
 
         */
587
 
        @Override
588
 
    protected void resetValue() {
589
 
                IInternalVariable iv = getCurrentInternalVariable();
590
 
                if ( iv != null ) {
591
 
                        resetStatus();
592
 
                        iv.resetValue();
593
 
                        fireChangeEvent( DebugEvent.STATE );
594
 
                }
595
 
        }
596
 
 
597
 
        private String processExpression( String oldExpression ) {
598
 
                return oldExpression;
599
 
        }
600
 
 
601
 
        /* (non-Javadoc)
602
 
         * @see org.eclipse.cdt.debug.internal.core.model.AbstractCVariable#dispose()
603
 
         */
604
 
        @Override
605
 
    public void dispose() {
606
 
                // Hack: do not destroy local variables
607
 
                internalDispose( false );
608
 
                setDisposed( true );
609
 
        }
610
 
 
611
 
        public int sizeof() {
612
 
                IInternalVariable iv = getCurrentInternalVariable(); 
613
 
                return ( iv != null ) ? iv.sizeof() : -1;
614
 
        }
615
 
 
616
 
        /**
617
 
         * Compares the original internal variables.
618
 
         * @see java.lang.Object#equals(java.lang.Object)
619
 
         */
620
 
        @Override
621
 
    public boolean equals( Object obj ) {
622
 
                if ( obj instanceof CVariable ) {
623
 
                        // A disposed copy can be stored in the viewer. 
624
 
                        // false should be returned to force the viewer to 
625
 
                        // replace it by a new variable. See bug #115385
626
 
                        if ( isDisposed() != ((CVariable)obj).isDisposed() )
627
 
                                return false;
628
 
                        IInternalVariable iv = getOriginal();
629
 
                        return ( iv != null ) ? iv.equals( ((CVariable)obj).getOriginal() ) : false;
630
 
                }
631
 
                return false;
632
 
        }
633
 
 
634
 
        protected boolean sameVariable( ICDIVariableDescriptor vo ) {
635
 
                IInternalVariable iv = getOriginal();
636
 
                return ( iv != null && iv.isSameDescriptor( vo ) );
637
 
        }
638
 
 
639
 
        protected void setFormat( CVariableFormat format ) {
640
 
                fFormat = format;
641
 
        }
642
 
 
643
 
        /* (non-Javadoc)
644
 
         * @see org.eclipse.cdt.debug.core.model.ICVariable#getExpressionString()
645
 
         */
646
 
        public String getExpressionString() throws DebugException {
647
 
                IInternalVariable iv = getCurrentInternalVariable(); 
648
 
                return ( iv != null ) ? iv.getQualifiedName() : null;
649
 
        }
650
 
 
651
 
        /* (non-Javadoc)
652
 
         * @see org.eclipse.cdt.debug.internal.core.model.AbstractCVariable#preserve()
653
 
         */
654
 
        @Override
655
 
    protected void preserve() {
656
 
                resetStatus();
657
 
                IInternalVariable iv = getCurrentInternalVariable(); 
658
 
                if ( iv != null )
659
 
                        iv.preserve();
660
 
        }
661
 
 
662
 
        protected void internalDispose( boolean destroy ) {
663
 
                getCDISession().getEventManager().removeEventListener( fEventListenerWrapper );
664
 
                IInternalVariable iv = getOriginal();
665
 
                if ( iv != null )
666
 
                        iv.dispose( destroy );
667
 
                iv = getShadow();
668
 
                if ( iv != null )
669
 
                        iv.dispose( destroy );
670
 
        }
671
 
        
672
 
        protected boolean isDisposed() {
673
 
                return fIsDisposed;
674
 
        }
675
 
 
676
 
        protected void setDisposed( boolean isDisposed ) {
677
 
                fIsDisposed = isDisposed;
678
 
        }
679
 
 
680
 
        protected void invalidateValue() {
681
 
                resetStatus();
682
 
                IInternalVariable iv = getCurrentInternalVariable();
683
 
                if ( iv != null )
684
 
                        iv.invalidateValue();
685
 
        }
686
 
        
687
 
        protected void setName( String name ) {
688
 
                fName = name;
689
 
        }
690
 
 
691
 
        public ICDIObject getCdiObject() {
692
 
                IInternalVariable iv = getCurrentInternalVariable();
693
 
                if ( iv != null ) {
694
 
                        return iv.getCdiObject();
695
 
                }
696
 
                return null;
697
 
        }
698
 
        
699
 
        protected CSettingsManager getFormatManager() {
700
 
                return ((CDebugTarget) getDebugTarget()).getFormatManager();
701
 
        }
702
 
        
703
 
        /**
704
 
         * used to concatenate multiple names to a single identifier 
705
 
         */
706
 
        private final static String NAME_PART_SEPARATOR = "-"; //$NON-NLS-1$
707
 
 
708
 
        /**
709
 
         * suffix used to identify format informations
710
 
         */
711
 
        private final static String FORMAT_SUFFIX = NAME_PART_SEPARATOR + "(format)"; //$NON-NLS-1$
712
 
 
713
 
        /**
714
 
         * suffix used to identify cast settings
715
 
         */
716
 
        private final static String CAST_SUFFIX = NAME_PART_SEPARATOR + "(cast)"; //$NON-NLS-1$
717
 
 
718
 
        /**
719
 
         * suffix used to identify cast to array settings
720
 
         */
721
 
        private final static String CAST_TO_ARRAY_SUFFIX = NAME_PART_SEPARATOR + "(cast_to_array)";  //$NON-NLS-1$
722
 
 
723
 
        /** retrieve the identification for this variable.
724
 
         * @return a string identifying this variable, to be used to store settings
725
 
         * @throws DebugException
726
 
         */
727
 
        String getVariableID() throws DebugException {
728
 
        return getName(); // TODO: better identification if multiple variables have the same name
729
 
    }
730
 
   
731
 
    /** helper to generate a string id used to persist the settings.
732
 
     * @param next_obj next object to encode into the id
733
 
     * @param buf contains the id of the part encoded so far.
734
 
     * @throws DebugException
735
 
     */
736
 
    static private void buildPesistID( CDebugElement next_obj, StringBuffer buf ) throws DebugException {
737
 
                if ( next_obj instanceof CVariable ) {
738
 
                        CVariable cVariableParent = (CVariable) next_obj;
739
 
                        buf.append( NAME_PART_SEPARATOR );
740
 
                        buf.append( cVariableParent.getVariableID() );
741
 
                        buildPesistID( cVariableParent.getParent(), buf );
742
 
                } else if ( next_obj instanceof CStackFrame ) {
743
 
                        buf.append(NAME_PART_SEPARATOR);
744
 
                        // TODO: better identification if multiple functions have the same name (say for static functions)
745
 
                        buf.append( ((CStackFrame)next_obj ).getFunction() );
746
 
                } else if ( next_obj instanceof CDebugTarget ) {
747
 
                        // global, we use a root NAME_PART_SEPARATOR as indicator of that
748
 
                        buf.append( NAME_PART_SEPARATOR );
749
 
                } else if ( next_obj instanceof AbstractCValue ) {
750
 
                        // index or indirection.
751
 
                        AbstractCValue av = (AbstractCValue) next_obj;
752
 
                        buildPesistID( av.getParentVariable(), buf );                   
753
 
                }
754
 
        }
755
 
        
756
 
    /** returns an string used to identify this variable  
757
 
         * @return
758
 
         * @throws DebugException
759
 
         */
760
 
        private final String getPersistID() throws DebugException {
761
 
                StringBuffer id = new StringBuffer();
762
 
                id.append( getVariableID() );
763
 
                buildPesistID( getParent(), id );
764
 
                return id.toString();
765
 
        }
766
 
 
767
 
        /** stores the given format
768
 
         * @param format the format to be used for this variable
769
 
         */
770
 
        protected void storeFormat( CVariableFormat format ) {
771
 
                try {
772
 
                        String formatString = Integer.toString( format.getFormatNumber() );
773
 
 
774
 
                        getFormatManager().putValue( getPersistID() + FORMAT_SUFFIX, formatString );
775
 
                } catch ( DebugException e ) {
776
 
                        // if we do not get the name, we use the default format, no reason for the creation to fail too.
777
 
                        DebugPlugin.log( e );
778
 
                }
779
 
        }
780
 
        
781
 
        /** stores the cast information.
782
 
         * @param type the type to be displayed instead
783
 
         */
784
 
        protected void storeCast( String type ) {
785
 
                try {
786
 
                        String id = getPersistID() + CAST_SUFFIX;
787
 
                        getFormatManager().putValue( id, type );
788
 
                } catch ( DebugException e ) {
789
 
                        DebugPlugin.log( e );
790
 
                }
791
 
        }
792
 
 
793
 
        /** drops the cast information.
794
 
         */
795
 
        protected void forgetCast() {
796
 
                try {
797
 
                        String id = getPersistID() + CAST_SUFFIX;
798
 
                        getFormatManager().removeValue( id );
799
 
                } catch ( DebugException e ) {
800
 
                        DebugPlugin.log( e );
801
 
                }
802
 
        }
803
 
                
804
 
        /** stores the cast array information.
805
 
         * @param startIndex the first item to be displayed in the cast array operation
806
 
         * @param length the number of elements to display
807
 
         */
808
 
        protected void storeCastToArray(int startIndex, int length) {
809
 
                try {
810
 
                        // we persist the information in a (startIndex):(Length) format.
811
 
                        String content = Integer.toString( startIndex ) + ":" + Integer.toString( length ); //$NON-NLS-1$
812
 
                        getFormatManager().putValue( getPersistID() + CAST_TO_ARRAY_SUFFIX, content );
813
 
                } catch ( DebugException e ) {
814
 
                        DebugPlugin.log( e );
815
 
                }
816
 
        }
817
 
 
818
 
        /** drops previously stored cast array information.
819
 
         */
820
 
        protected void forgetCastToArray() {
821
 
                try {
822
 
                        String id = getPersistID() + CAST_TO_ARRAY_SUFFIX;
823
 
                        getFormatManager().removeValue( id );
824
 
                } catch ( DebugException e ) {
825
 
                        DebugPlugin.log( e );
826
 
                }
827
 
        }
828
 
                
829
 
        /**
830
 
         * restore the format stored previously for this variable.
831
 
         * Only sets explicitly retrieved formats in order to maintain defaults. 
832
 
         */
833
 
        protected void setInitialFormat() {
834
 
                try {
835
 
                        String persistID= getPersistID();
836
 
                        String stringFormat = getFormatManager().getValue( persistID + FORMAT_SUFFIX );
837
 
                        if ( stringFormat != null ) {
838
 
                                try {
839
 
                                        CVariableFormat format = CVariableFormat.getFormat( Integer.parseInt( stringFormat ) );
840
 
                                        setFormat( format );
841
 
                                } catch ( NumberFormatException e ) {
842
 
                                        DebugPlugin.log( e );
843
 
                                }
844
 
                        }
845
 
                        
846
 
                        if ( canCast() ) {
847
 
                                String castString = getFormatManager().getValue( persistID + CAST_SUFFIX );
848
 
                                if ( castString != null ) {
849
 
                                        cast( castString );
850
 
                                }
851
 
                        }
852
 
                        if ( canCastToArray() ) {
853
 
                                String castToArrayString = getFormatManager().getValue( persistID + CAST_TO_ARRAY_SUFFIX );
854
 
                                if (castToArrayString != null) {
855
 
                                        int index = castToArrayString.indexOf( ':' );
856
 
                                        if ( index > 0 ) {
857
 
                                                try {
858
 
                                                        int beg = Integer.parseInt( castToArrayString.substring( 0, index ) );
859
 
                                                        int num = Integer.parseInt( castToArrayString.substring( index + 1 ) );
860
 
                                                        castToArray( beg, num );
861
 
                                                } catch ( NumberFormatException e ) {
862
 
                                                        DebugPlugin.log( e );
863
 
                                                }
864
 
                                        } else {
865
 
                                                DebugPlugin.logMessage( "did not find expected : for cast to array", null ); //$NON-NLS-1$
866
 
                                        }
867
 
                                }
868
 
                        }
869
 
                } catch ( DebugException e ) {
870
 
                        DebugPlugin.log( e );
871
 
                        // we drop (and log) the exception here.
872
 
                        // even if the initial setup fails, we still want the complete creation to be successful
873
 
                }
874
 
        }
875
 
}