31
32
using System.Collections;
32
33
using System.Collections.Generic;
33
34
using System.Collections.ObjectModel;
35
using System.Runtime.InteropServices;
35
37
namespace Mono.Debugging.Client
37
39
public sealed class BreakpointStore: ICollection<BreakEvent>
41
static readonly StringComparer PathComparer;
42
static readonly bool IsWindows;
43
static readonly bool IsMac;
45
static BreakpointStore ()
47
IsWindows = Path.DirectorySeparatorChar == '\\';
48
IsMac = !IsWindows && IsRunningOnMac ();
50
PathComparer = IsWindows || IsMac ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal;
54
static extern int uname (IntPtr buf);
56
//From Managed.Windows.Forms/XplatUI
57
static bool IsRunningOnMac ()
59
IntPtr buf = IntPtr.Zero;
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);
70
if (buf != IntPtr.Zero)
71
Marshal.FreeHGlobal (buf);
39
76
List<BreakEvent> breakpoints = new List<BreakEvent> ();
94
public Breakpoint Add (string filename, int line, int column)
96
return Add (filename, line, column, true);
57
99
public Breakpoint Add (string filename, int line)
59
return Add (filename, line, true);
101
return Add (filename, line, 1, true);
62
public Breakpoint Add (string filename, int line, bool activate)
104
public Breakpoint Add (string filename, int line, int column, bool activate)
66
Breakpoint bp = new Breakpoint (filename, line);
109
Breakpoint bp = new Breakpoint (filename, line, column);
80
125
breakpoints.Add (bp);
82
127
OnBreakEventAdded (bp);
86
public Catchpoint AddCatchpoint (string exceptioName)
132
public Catchpoint AddCatchpoint (string exceptionName)
90
Catchpoint cp = new Catchpoint (exceptioName);
137
Catchpoint cp = new Catchpoint (exceptionName);
95
public bool Remove (string filename, int line)
143
public bool Remove (string filename, int line, int column)
99
filename = System.IO.Path.GetFullPath (filename);
148
filename = Path.GetFullPath (filename);
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);
130
181
if (!IsReadOnly && breakpoints.Remove (bp)) {
131
182
OnBreakEventRemoved (bp);
137
public Breakpoint Toggle (string filename, int line)
189
public Breakpoint Toggle (string filename, int line, int column)
142
194
ReadOnlyCollection<Breakpoint> col = GetBreakpointsAtFileLine (filename, line);
143
195
if (col.Count > 0) {
144
foreach (Breakpoint bp in col)
196
// Remove only the most-recently-added breakpoint on the specified line
197
Remove (col[col.Count - 1]);
149
return Add (filename, line);
201
return Add (filename, line, column);
153
204
public ReadOnlyCollection<Breakpoint> GetBreakpoints ()
256
307
NotifyBreakEventChanged (bp);
259
internal void AdjustBreakpointLine (Breakpoint bp, int newLine)
310
internal void AdjustBreakpointLine (Breakpoint bp, int newLine, int newColumn)
315
bp.SetAdjustedColumn (newColumn);
264
316
bp.SetAdjustedLine (newLine);
265
317
NotifyBreakEventChanged (bp);
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 ()) {
276
327
NotifyBreakEventChanged (bp);
356
static extern IntPtr realpath (string path, IntPtr buffer);
358
static string ResolveFullPath (string path)
361
return Path.GetFullPath (path);
363
const int PATHMAX = 4096 + 1;
364
IntPtr buffer = IntPtr.Zero;
367
buffer = Marshal.AllocHGlobal (PATHMAX);
368
var result = realpath (path, buffer);
369
return result == IntPtr.Zero ? "" : Marshal.PtrToStringAuto (buffer);
371
if (buffer != IntPtr.Zero)
372
Marshal.FreeHGlobal (buffer);
305
376
public static bool FileNameEquals (string file1, string file2)
307
if (System.IO.Path.DirectorySeparatorChar == '\\')
308
return string.Compare (file1, file2, true) == 0;
310
return file1 == file2;
378
if (PathComparer.Compare (file1, file2) == 0)
381
var rfile1 = ResolveFullPath (file1);
382
var rfile2 = ResolveFullPath (file2);
384
return PathComparer.Compare (rfile1, rfile2) == 0;
313
387
internal bool EnableBreakEvent (BreakEvent be, bool enabled)
318
393
EventHandler<BreakEventArgs> evnt = BreakEventEnableStatusChanged;
319
394
if (evnt != null)
320
395
evnt (this, new BreakEventArgs (be));
321
396
NotifyStatusChanged (be);