~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to src/core/Mono.Debugging/Mono.Debugging.Client/BreakpointStore.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
//
27
27
 
28
28
using System;
 
29
using System.IO;
29
30
using System.Linq;
30
31
using System.Xml;
31
32
using System.Collections;
32
33
using System.Collections.Generic;
33
34
using System.Collections.ObjectModel;
 
35
using System.Runtime.InteropServices;
34
36
 
35
37
namespace Mono.Debugging.Client
36
38
{
37
39
        public sealed class BreakpointStore: ICollection<BreakEvent>
38
40
        {
 
41
                static readonly StringComparer PathComparer;
 
42
                static readonly bool IsWindows;
 
43
                static readonly bool IsMac;
 
44
 
 
45
                static BreakpointStore ()
 
46
                {
 
47
                        IsWindows = Path.DirectorySeparatorChar == '\\';
 
48
                        IsMac = !IsWindows && IsRunningOnMac ();
 
49
 
 
50
                        PathComparer = IsWindows || IsMac ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal;
 
51
                }
 
52
 
 
53
                [DllImport ("libc")]
 
54
                static extern int uname (IntPtr buf);
 
55
 
 
56
                //From Managed.Windows.Forms/XplatUI
 
57
                static bool IsRunningOnMac ()
 
58
                {
 
59
                        IntPtr buf = IntPtr.Zero;
 
60
                        try {
 
61
                                buf = Marshal.AllocHGlobal (8192);
 
62
                                // This is a hacktastic way of getting sysname from uname ()
 
63
                                if (uname (buf) == 0) {
 
64
                                        string os = Marshal.PtrToStringAnsi (buf);
 
65
                                        if (os == "Darwin")
 
66
                                                return true;
 
67
                                }
 
68
                        } catch {
 
69
                        } finally {
 
70
                                if (buf != IntPtr.Zero)
 
71
                                        Marshal.FreeHGlobal (buf);
 
72
                        }
 
73
                        return false;
 
74
                }
 
75
 
39
76
                List<BreakEvent> breakpoints = new List<BreakEvent> ();
40
77
                
41
78
                public int Count {
54
91
                        }
55
92
                }
56
93
 
 
94
                public Breakpoint Add (string filename, int line, int column)
 
95
                {
 
96
                        return Add (filename, line, column, true);
 
97
                }
 
98
 
57
99
                public Breakpoint Add (string filename, int line)
58
100
                {
59
 
                        return Add (filename, line, true);
 
101
                        return Add (filename, line, 1, true);
60
102
                }
61
103
                
62
 
                public Breakpoint Add (string filename, int line, bool activate)
 
104
                public Breakpoint Add (string filename, int line, int column, bool activate)
63
105
                {
64
106
                        if (IsReadOnly)
65
107
                                return null;
66
 
                        Breakpoint bp = new Breakpoint (filename, line);
 
108
 
 
109
                        Breakpoint bp = new Breakpoint (filename, line, column);
67
110
                        Add (bp);
 
111
 
68
112
                        return bp;
69
113
                }
70
114
 
77
121
                {
78
122
                        if (IsReadOnly)
79
123
                                return false;
 
124
 
80
125
                        breakpoints.Add (bp);
81
126
                        bp.Store = this;
82
127
                        OnBreakEventAdded (bp);
 
128
 
83
129
                        return true;
84
130
                }
85
131
                
86
 
                public Catchpoint AddCatchpoint (string exceptioName)
 
132
                public Catchpoint AddCatchpoint (string exceptionName)
87
133
                {
88
134
                        if (IsReadOnly)
89
135
                                return null;
90
 
                        Catchpoint cp = new Catchpoint (exceptioName);
 
136
 
 
137
                        Catchpoint cp = new Catchpoint (exceptionName);
91
138
                        Add (cp);
 
139
 
92
140
                        return cp;
93
141
                }
94
142
                
95
 
                public bool Remove (string filename, int line)
 
143
                public bool Remove (string filename, int line, int column)
96
144
                {
97
145
                        if (IsReadOnly)
98
146
                                return false;
99
 
                        filename = System.IO.Path.GetFullPath (filename);
 
147
 
 
148
                        filename = Path.GetFullPath (filename);
100
149
                        
101
150
                        for (int n=0; n<breakpoints.Count; n++) {
102
151
                                Breakpoint bp = breakpoints [n] as Breakpoint;
103
 
                                if (bp != null && FileNameEquals (bp.FileName, filename) && bp.Line == line) {
 
152
                                if (bp != null && FileNameEquals (bp.FileName, filename) &&
 
153
                                    (bp.OriginalLine == line || bp.Line == line) &&
 
154
                                    (bp.OriginalColumn == column || bp.Column == column)) {
104
155
                                        breakpoints.RemoveAt (n);
105
156
                                        OnBreakEventRemoved (bp);
106
157
                                        n--;
130
181
                        if (!IsReadOnly && breakpoints.Remove (bp)) {
131
182
                                OnBreakEventRemoved (bp);
132
183
                                return true;
133
 
                        } else
134
 
                                return false;
 
184
                        }
 
185
 
 
186
                        return false;
135
187
                }
136
188
                
137
 
                public Breakpoint Toggle (string filename, int line)
 
189
                public Breakpoint Toggle (string filename, int line, int column)
138
190
                {
139
191
                        if (IsReadOnly)
140
192
                                return null;
141
193
                        
142
194
                        ReadOnlyCollection<Breakpoint> col = GetBreakpointsAtFileLine (filename, line);
143
195
                        if (col.Count > 0) {
144
 
                                foreach (Breakpoint bp in col)
145
 
                                        Remove (bp);
 
196
                                // Remove only the most-recently-added breakpoint on the specified line
 
197
                                Remove (col[col.Count - 1]);
146
198
                                return null;
147
199
                        }
148
 
                        else {
149
 
                                return Add (filename, line);
150
 
                        }
 
200
 
 
201
                        return Add (filename, line, column);
151
202
                }
152
203
                
153
204
                public ReadOnlyCollection<Breakpoint> GetBreakpoints ()
175
226
                        List<Breakpoint> list = new List<Breakpoint> ();
176
227
                        
177
228
                        try {
178
 
                                filename = System.IO.Path.GetFullPath (filename);
 
229
                                filename = Path.GetFullPath (filename);
179
230
                        } catch {
180
231
                                return list.AsReadOnly ();
181
232
                        }
194
245
                        List<Breakpoint> list = new List<Breakpoint> ();
195
246
                        
196
247
                        try {
197
 
                                filename = System.IO.Path.GetFullPath (filename);
 
248
                                filename = Path.GetFullPath (filename);
198
249
                        } catch {
199
250
                                return list.AsReadOnly ();
200
251
                        }
256
307
                        NotifyBreakEventChanged (bp);
257
308
                }
258
309
                
259
 
                internal void AdjustBreakpointLine (Breakpoint bp, int newLine)
 
310
                internal void AdjustBreakpointLine (Breakpoint bp, int newLine, int newColumn)
260
311
                {
261
312
                        if (IsReadOnly)
262
313
                                return;
263
 
                        
 
314
 
 
315
                        bp.SetAdjustedColumn (newColumn);
264
316
                        bp.SetAdjustedLine (newLine);
265
317
                        NotifyBreakEventChanged (bp);
266
318
                }
270
322
                        if (IsReadOnly)
271
323
                                return;
272
324
                        
273
 
                        foreach (Breakpoint bp in breakpoints.Where (b => b is Breakpoint).ToArray ()) {
274
 
                                if (bp.HasAdjustedLine) {
275
 
                                        bp.ResetAdjustedLine ();
 
325
                        foreach (Breakpoint bp in breakpoints.OfType<Breakpoint> ().ToArray ()) {
 
326
                                if (bp.Reset ())
276
327
                                        NotifyBreakEventChanged (bp);
277
 
                                }
278
328
                        }
279
329
                }
280
330
                
302
352
                        }
303
353
                }
304
354
 
 
355
                [DllImport ("libc")]
 
356
                static extern IntPtr realpath (string path, IntPtr buffer);
 
357
 
 
358
                static string ResolveFullPath (string path)
 
359
                {
 
360
                        if (IsWindows)
 
361
                                return Path.GetFullPath (path);
 
362
 
 
363
                        const int PATHMAX = 4096 + 1;
 
364
                        IntPtr buffer = IntPtr.Zero;
 
365
 
 
366
                        try {
 
367
                                buffer = Marshal.AllocHGlobal (PATHMAX);
 
368
                                var result = realpath (path, buffer);
 
369
                                return result == IntPtr.Zero ? "" : Marshal.PtrToStringAuto (buffer);
 
370
                        } finally {
 
371
                                if (buffer != IntPtr.Zero)
 
372
                                        Marshal.FreeHGlobal (buffer);
 
373
                        }
 
374
                }
 
375
 
305
376
                public static bool FileNameEquals (string file1, string file2)
306
377
                {
307
 
                        if (System.IO.Path.DirectorySeparatorChar == '\\')
308
 
                                return string.Compare (file1, file2, true) == 0;
309
 
                        else
310
 
                                return file1 == file2;
 
378
                        if (PathComparer.Compare (file1, file2) == 0)
 
379
                                return true;
 
380
 
 
381
                        var rfile1 = ResolveFullPath (file1);
 
382
                        var rfile2 = ResolveFullPath (file2);
 
383
 
 
384
                        return PathComparer.Compare (rfile1, rfile2) == 0;
311
385
                }
312
386
                
313
387
                internal bool EnableBreakEvent (BreakEvent be, bool enabled)
314
388
                {
315
389
                        if (IsReadOnly)
316
390
                                return false;
 
391
 
317
392
                        OnChanged ();
318
393
                        EventHandler<BreakEventArgs> evnt = BreakEventEnableStatusChanged;
319
394
                        if (evnt != null)
320
395
                                evnt (this, new BreakEventArgs (be));
321
396
                        NotifyStatusChanged (be);
 
397
 
322
398
                        return true;
323
399
                }
324
400