forked from nygard/class-dump
/
NSScanner-Extensions.m
190 lines (135 loc) · 4.82 KB
/
NSScanner-Extensions.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
// -*- mode: ObjC -*-
// This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files.
// Copyright (C) 1997-1998, 2000-2001, 2004-2011 Steve Nygard.
#import "NSScanner-Extensions.h"
#import "NSString-Extensions.h"
@implementation NSScanner (CDExtensions)
// other: $_:*
// start: alpha + other
// remainder: alnum + other
+ (NSCharacterSet *)cdOtherCharacterSet;
{
static NSCharacterSet *otherCharacterSet = nil;
if (otherCharacterSet == nil)
otherCharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@"$_:*"] retain];
return otherCharacterSet;
}
+ (NSCharacterSet *)cdIdentifierStartCharacterSet;
{
static NSCharacterSet *identifierStartCharacterSet = nil;
if (identifierStartCharacterSet == nil) {
NSMutableCharacterSet *set = [[NSCharacterSet letterCharacterSet] mutableCopy];
[set formUnionWithCharacterSet:[NSScanner cdOtherCharacterSet]];
identifierStartCharacterSet = [set copy];
[set release];
}
return identifierStartCharacterSet;
}
+ (NSCharacterSet *)cdIdentifierCharacterSet;
{
static NSCharacterSet *identifierCharacterSet = nil;
if (identifierCharacterSet == nil) {
NSMutableCharacterSet *set = [[NSCharacterSet alphanumericCharacterSet] mutableCopy];
[set formUnionWithCharacterSet:[NSScanner cdOtherCharacterSet]];
identifierCharacterSet = [set copy];
[set release];
}
return identifierCharacterSet;
}
+ (NSCharacterSet *)cdTemplateTypeCharacterSet;
{
static NSCharacterSet *templateTypeCharacterSet = nil;
if (templateTypeCharacterSet == nil)
templateTypeCharacterSet = [[[NSCharacterSet characterSetWithCharactersInString:@"<,>"] invertedSet] retain];
return templateTypeCharacterSet;
}
- (NSString *)peekCharacter;
{
//[self skipCharacters];
if ([self isAtEnd])
return nil;
return [[self string] substringWithRange:NSMakeRange([self scanLocation], 1)];
}
- (unichar)peekChar;
{
return [[self string] characterAtIndex:[self scanLocation]];
}
- (BOOL)scanCharacter:(unichar *)value;
{
//[self skipCharacters];
if ([self isAtEnd])
return NO;
unichar ch = [[self string] characterAtIndex:[self scanLocation]];
if (value != NULL)
*value = ch;
[self setScanLocation:[self scanLocation] + 1];
return YES;
}
- (BOOL)scanCharacterFromSet:(NSCharacterSet *)set intoString:(NSString **)value;
{
//[self skipCharacters];
if ([self isAtEnd])
return NO;
unichar ch = [[self string] characterAtIndex:[self scanLocation]];
if ([set characterIsMember:ch]) {
if (value != NULL) {
*value = [NSString stringWithUnichar:ch];
}
[self setScanLocation:[self scanLocation] + 1];
return YES;
}
return NO;
}
// On 10.3 (7D24) the Foundation scanCharactersFromSet:intoString: inverts the set each call, creating an autoreleased CFCharacterSet.
// This cuts the total CFCharacterSet alloctions (when run on Foundation) from 161682 down to 17.
// This works for my purposes, but I haven't tested it to make sure it's fully compatible with the standard version.
- (BOOL)my_scanCharactersFromSet:(NSCharacterSet *)set intoString:(NSString **)value;
{
NSCharacterSet *skipSet;
NSUInteger currentLocation = [self scanLocation];
// Skip over characters
skipSet = [self charactersToBeSkipped];
while ([self isAtEnd] == NO) {
unichar ch;
ch = [[self string] characterAtIndex:currentLocation];
if ([skipSet characterIsMember:ch] == NO)
break;
currentLocation++;
[self setScanLocation:currentLocation];
}
NSRange matchedRange = NSMakeRange(currentLocation, 0);
while ([self isAtEnd] == NO) {
unichar ch = [[self string] characterAtIndex:currentLocation];
if ([set characterIsMember:ch] == NO)
break;
currentLocation++;
[self setScanLocation:currentLocation];
}
matchedRange.length = currentLocation - matchedRange.location;
if (matchedRange.length == 0)
return NO;
if (value != NULL) {
*value = [[self string] substringWithRange:matchedRange];
}
return YES;
}
- (BOOL)scanIdentifierIntoString:(NSString **)stringPointer;
{
NSString *start, *remainder;
if ([self scanString:@"?" intoString:stringPointer]) {
return YES;
}
if ([self scanCharacterFromSet:[NSScanner cdIdentifierStartCharacterSet] intoString:&start]) {
NSString *str;
if ([self my_scanCharactersFromSet:[NSScanner cdIdentifierCharacterSet] intoString:&remainder]) {
str = [start stringByAppendingString:remainder];
} else {
str = start;
}
if (stringPointer != NULL)
*stringPointer = str;
return YES;
}
return NO;
}
@end