3 * Copyright (c) 2007 - 2011, Blue Static <http://www.bluestatic.org>
5 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
6 * General Public License as published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
10 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public License along with this program; if not,
14 * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
17 #import "Breakpoint.h"
19 #import "PreferenceNames.h"
21 NSString
* const kBreakpointTypeFile
= @
"line";
22 NSString
* const kBreakpointTypeFunctionEntry
= @
"call";
24 @implementation Breakpoint
{
25 NSString
* __weak _type
;
26 unsigned long _debuggerId
;
29 NSData
* _secureBookmark
;
30 NSURL
* _secureFileAccess
;
32 NSString
* _functionName
;
35 + (instancetype
)breakpointAtLine
:(unsigned long)line inFile
:(NSString
*)file
37 Breakpoint
* breakpoint
= [[Breakpoint alloc
] init
];
38 breakpoint
->_type
= kBreakpointTypeFile
;
39 breakpoint
->_file
= [file copy
];
40 breakpoint
->_line
= line
;
44 + (instancetype
)breakpointOnFunctionNamed
:(NSString
*)name
46 Breakpoint
* breakpoint
= [[Breakpoint alloc
] init
];
47 breakpoint
->_type
= kBreakpointTypeFunctionEntry
;
48 breakpoint
->_functionName
= [name copy
];
52 - (instancetype
)initWithDictionary
:(NSDictionary
*)dict
54 if ((self = [super init
])) {
55 NSString
* type
= [dict valueForKey
:@
"type"];
56 if (!type ||
[type isEqualToString
:kBreakpointTypeFile
]) {
57 _type
= kBreakpointTypeFile
;
58 _file
= [[dict valueForKey
:@
"file"] copy
];
59 _line
= [[dict valueForKey
:@
"line"] intValue
];
60 _secureBookmark
= [[dict valueForKey
:@
"secureBookmark"] copy
];
61 } else if ([type isEqualToString
:kBreakpointTypeFunctionEntry
]) {
62 _type
= kBreakpointTypeFunctionEntry
;
63 _functionName
= [[dict valueForKey
:@
"function"] copy
];
65 [NSException raise
:NSInvalidArgumentException
66 format
:@
"Unknown Breakpoint type: %@", type
];
73 if (_secureFileAccess
)
74 [self stopSecureFileAccess
];
78 * Returns the string to display in the breakpoints list.
80 - (NSString
*)displayValue
82 if (self.type
== kBreakpointTypeFile
) {
83 return [NSString stringWithFormat
:@
"%@:%ld", self.file
, self.line
];
84 } else if (self.type
== kBreakpointTypeFunctionEntry
) {
85 return [NSString stringWithFormat
:@
"%@()", self.functionName
];
91 * Returns the transformed path for the breakpoint, as Xdebug needs it
93 - (NSString
*)transformedPath
95 NSString
* path
= self.file
;
97 NSMutableArray
* transforms
= [[NSUserDefaults standardUserDefaults
] mutableArrayValueForKey
:kPrefPathReplacements
];
98 if (!transforms ||
[transforms count
] < 1)
101 for (NSDictionary
* replacement
in transforms
)
104 stringByReplacingOccurrencesOfString
:[replacement valueForKey
:@
"local"]
105 withString
:[replacement valueForKey
:@
"remote"]
112 - (BOOL)isEqual
:(id)obj
114 if (![obj isKindOfClass
:[self class]]) {
118 Breakpoint
* other
= obj
;
119 if (self.type
!= other.type
) {
123 if (self.type
== kBreakpointTypeFile
) {
124 return [self.file isEqualToString
:other.file
] && self.line
== other.line
;
125 } else if (self.type
== kBreakpointTypeFunctionEntry
) {
126 return [self.functionName isEqualToString
:other.functionName
];
132 - (NSDictionary
*)dictionary
134 if (self.type
== kBreakpointTypeFile
) {
135 NSMutableDictionary
* dict
= [NSMutableDictionary dictionaryWithDictionary
:@
{
138 @
"line" : @
(self.line
),
140 if (self.secureBookmark
)
141 [dict setObject
:self.secureBookmark forKey
:@
"secureBookmark"];
143 } else if (self.type
== kBreakpointTypeFunctionEntry
) {
146 @
"function" : self.functionName
152 - (BOOL)createSecureBookmark
154 NSURL
* fileURL
= [NSURL fileURLWithPath
:self.file
];
155 return [self _createSecureBookmarkWithURL
:fileURL
];
158 - (BOOL)_createSecureBookmarkWithURL
:(NSURL
*)url
161 NSData
* secureBookmark
= [url bookmarkDataWithOptions
:NSURLBookmarkCreationWithSecurityScope | NSURLBookmarkCreationSecurityScopeAllowOnlyReadAccess
162 includingResourceValuesForKeys
:nil
165 if (secureBookmark
) {
166 self.secureBookmark
= secureBookmark
;
169 NSLog(@
"Failed to create secure bookmark: %@", error
);
174 - (BOOL)startSecureFileAccess
176 assert(self.type
== kBreakpointTypeFile
);
177 if (_secureFileAccess
)
179 if (!_secureBookmark
)
184 _secureFileAccess
= [NSURL URLByResolvingBookmarkData
:_secureBookmark
185 options
:NSURLBookmarkResolutionWithSecurityScope
187 bookmarkDataIsStale
:&isStale
190 NSLog(@
"Failed to access file via secure bookmark: %@", error
);
194 [self _createSecureBookmarkWithURL
:_secureFileAccess
];
196 return [_secureFileAccess startAccessingSecurityScopedResource
];
199 - (BOOL)stopSecureFileAccess
201 assert(self.type
== kBreakpointTypeFile
);
202 if (!_secureFileAccess
)
204 if (!_secureBookmark
)
207 [_secureFileAccess stopAccessingSecurityScopedResource
];
208 _secureFileAccess
= nil;
212 - (NSString
*)description
214 return [NSString stringWithFormat
:@
"Breakpoint %@", [[self dictionary
] description
]];