Speculative fix for a crash if a handler cannot be found for a transaction.
[macgdbp.git] / Source / Breakpoint.m
1 /*
2 * MacGDBp
3 * Copyright (c) 2007 - 2011, Blue Static <http://www.bluestatic.org>
4 *
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.
8 *
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.
12 *
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
15 */
16
17 #import "Breakpoint.h"
18
19 #import "PreferenceNames.h"
20
21 NSString* const kBreakpointTypeFile = @"line";
22 NSString* const kBreakpointTypeFunctionEntry = @"call";
23
24 @implementation Breakpoint {
25 NSString* __weak _type;
26 unsigned long _debuggerId;
27
28 NSString* _file;
29
30 NSString* _functionName;
31 }
32
33 + (instancetype)breakpointAtLine:(unsigned long)line inFile:(NSString*)file
34 {
35 Breakpoint* breakpoint = [[Breakpoint alloc] init];
36 breakpoint->_type = kBreakpointTypeFile;
37 breakpoint->_file = [file copy];
38 breakpoint->_line = line;
39 return breakpoint;
40 }
41
42 + (instancetype)breakpointOnFunctionNamed:(NSString*)name
43 {
44 Breakpoint* breakpoint = [[Breakpoint alloc] init];
45 breakpoint->_type = kBreakpointTypeFunctionEntry;
46 breakpoint->_functionName = [name copy];
47 return breakpoint;
48 }
49
50 - (instancetype)initWithDictionary:(NSDictionary*)dict
51 {
52 if ((self = [super init])) {
53 NSString* type = [dict valueForKey:@"type"];
54 if (!type || [type isEqualToString:kBreakpointTypeFile]) {
55 _type = kBreakpointTypeFile;
56 _file = [[dict valueForKey:@"file"] copy];
57 _line = [[dict valueForKey:@"line"] intValue];
58 } else if ([type isEqualToString:kBreakpointTypeFunctionEntry]) {
59 _type = kBreakpointTypeFunctionEntry;
60 _functionName = [[dict valueForKey:@"function"] copy];
61 } else {
62 [NSException raise:NSInvalidArgumentException
63 format:@"Unknown Breakpoint type: %@", type];
64 }
65 }
66 return self;
67 }
68
69 /**
70 * Returns the string to display in the breakpoints list.
71 */
72 - (NSString*)displayValue
73 {
74 if (self.type == kBreakpointTypeFile) {
75 return [NSString stringWithFormat:@"%@:%ld", self.file, self.line];
76 } else if (self.type == kBreakpointTypeFunctionEntry) {
77 return [NSString stringWithFormat:@"%@()", self.functionName];
78 }
79 return nil;
80 }
81
82 /**
83 * Returns the transformed path for the breakpoint, as Xdebug needs it
84 */
85 - (NSString*)transformedPath
86 {
87 NSString* path = self.file;
88
89 NSMutableArray* transforms = [[NSUserDefaults standardUserDefaults] mutableArrayValueForKey:kPrefPathReplacements];
90 if (!transforms || [transforms count] < 1)
91 return path;
92
93 for (NSDictionary* replacement in transforms)
94 {
95 path = [path
96 stringByReplacingOccurrencesOfString:[replacement valueForKey:@"local"]
97 withString:[replacement valueForKey:@"remote"]
98 ];
99 }
100
101 return path;
102 }
103
104 - (BOOL)isEqual:(id)obj
105 {
106 if (![obj isKindOfClass:[self class]]) {
107 return NO;
108 }
109
110 Breakpoint* other = obj;
111 if (self.type != other.type) {
112 return NO;
113 }
114
115 if (self.type == kBreakpointTypeFile) {
116 return [self.file isEqualToString:other.file] && self.line == other.line;
117 } else if (self.type == kBreakpointTypeFunctionEntry) {
118 return [self.functionName isEqualToString:other.functionName];
119 }
120
121 return NO;
122 }
123
124 - (NSDictionary*)dictionary
125 {
126 if (self.type == kBreakpointTypeFile) {
127 return @{
128 @"type" : self.type,
129 @"file" : self.file,
130 @"line" : @(self.line)
131 };
132 } else if (self.type == kBreakpointTypeFunctionEntry) {
133 return @{
134 @"type" : self.type,
135 @"function" : self.functionName
136 };
137 }
138 return nil;
139 }
140
141 - (NSString*)description
142 {
143 return [NSString stringWithFormat:@"Breakpoint %@", [[self dictionary] description]];
144 }
145
146 @end