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