OLD | NEW |
(Empty) | |
| 1 // This file is part of class-dump, a utility for examining the Objective-C seg
ment of Mach-O files. |
| 2 // Copyright (C) 1997-1998, 2000-2001, 2004-2010 Steve Nygard. |
| 3 |
| 4 #import "CDTypeFormatterUnitTest.h" |
| 5 |
| 6 #import <Foundation/Foundation.h> |
| 7 #import "NSError-CDExtensions.h" |
| 8 |
| 9 #import "CDType.h" |
| 10 #import "CDTypeFormatter.h" |
| 11 #import "CDTypeLexer.h" |
| 12 #import "CDTypeParser.h" |
| 13 |
| 14 @implementation CDTypeFormatterUnitTest |
| 15 |
| 16 - (void)dealloc; |
| 17 { |
| 18 [typeFormatter release]; |
| 19 [super dealloc]; |
| 20 } |
| 21 |
| 22 - (void)setUp; |
| 23 { |
| 24 typeFormatter = [[CDTypeFormatter alloc] init]; |
| 25 } |
| 26 |
| 27 - (void)tearDown; |
| 28 { |
| 29 [typeFormatter release]; |
| 30 typeFormatter = nil; |
| 31 } |
| 32 |
| 33 - (void)testVariableName:(NSString *)aVariableName type:(NSString *)aType expect
edResult:(NSString *)expectedResult; |
| 34 { |
| 35 NSString *result; |
| 36 |
| 37 result = [typeFormatter formatVariable:aVariableName type:aType symbolRefere
nces:nil]; |
| 38 STAssertEqualObjects(expectedResult, result, @""); |
| 39 } |
| 40 |
| 41 - (void)parseAndEncodeType:(NSString *)originalType; |
| 42 { |
| 43 CDTypeParser *typeParser; |
| 44 CDType *parsedType; |
| 45 NSString *reencodedType; |
| 46 NSError *error; |
| 47 |
| 48 typeParser = [[[CDTypeParser alloc] initWithType:originalType] autorelease]; |
| 49 STAssertNotNil(typeParser, @"Failed to create parser"); |
| 50 |
| 51 parsedType = [typeParser parseType:&error]; |
| 52 STAssertNotNil(parsedType, @"-[CDTypeParser parseType:] error: %@", [error m
yExplanation]); |
| 53 |
| 54 reencodedType = [parsedType typeString]; |
| 55 STAssertEqualObjects(originalType, reencodedType, @""); |
| 56 } |
| 57 |
| 58 - (void)testBasicTypes; |
| 59 { |
| 60 //[self variableName:@"var" testType:@"i" expectedResult:@"int var"]; |
| 61 |
| 62 [self testVariableName:@"var" type:@"c" expectedResult:@"BOOL var"]; |
| 63 [self testVariableName:@"var" type:@"i" expectedResult:@"int var"]; |
| 64 [self testVariableName:@"var" type:@"s" expectedResult:@"short var"]; |
| 65 [self testVariableName:@"var" type:@"l" expectedResult:@"long var"]; |
| 66 [self testVariableName:@"var" type:@"q" expectedResult:@"long long var"]; |
| 67 [self testVariableName:@"var" type:@"C" expectedResult:@"unsigned char var"]
; |
| 68 [self testVariableName:@"var" type:@"I" expectedResult:@"unsigned int var"]; |
| 69 [self testVariableName:@"var" type:@"S" expectedResult:@"unsigned short var"
]; |
| 70 [self testVariableName:@"var" type:@"L" expectedResult:@"unsigned long var"]
; |
| 71 [self testVariableName:@"var" type:@"Q" expectedResult:@"unsigned long long
var"]; |
| 72 [self testVariableName:@"var" type:@"f" expectedResult:@"float var"]; |
| 73 [self testVariableName:@"var" type:@"d" expectedResult:@"double var"]; |
| 74 [self testVariableName:@"var" type:@"B" expectedResult:@"_Bool var"]; |
| 75 [self testVariableName:@"var" type:@"v" expectedResult:@"void var"]; // TODO
: Doesn't make sense |
| 76 [self testVariableName:@"var" type:@"*" expectedResult:@"char *var"]; |
| 77 [self testVariableName:@"var" type:@"#" expectedResult:@"Class var"]; |
| 78 [self testVariableName:@"var" type:@":" expectedResult:@"SEL var"]; |
| 79 [self testVariableName:@"var" type:@"%" expectedResult:@"NXAtom var"]; |
| 80 [self testVariableName:@"var" type:@"?" expectedResult:@"void var"]; |
| 81 } |
| 82 |
| 83 - (void)testModifiers; |
| 84 { |
| 85 // The Distributed Object modifiers (in, inout, out, bycopy, byref, oneway)
are only for method parameters/return |
| 86 // values, so they will never have a variable name. |
| 87 |
| 88 // TODO (2003-12-20): Check whether const makes sense for ivars. |
| 89 [self testVariableName:nil type:@"ri" expectedResult:@"const int"]; |
| 90 [self testVariableName:nil type:@"ni" expectedResult:@"in int"]; |
| 91 [self testVariableName:nil type:@"Ni" expectedResult:@"inout int"]; |
| 92 [self testVariableName:nil type:@"oi" expectedResult:@"out int"]; |
| 93 [self testVariableName:nil type:@"Oi" expectedResult:@"bycopy int"]; |
| 94 [self testVariableName:nil type:@"Ri" expectedResult:@"byref int"]; |
| 95 [self testVariableName:nil type:@"Vi" expectedResult:@"oneway int"]; |
| 96 |
| 97 // These shouldn't happen in practice, but here's how they would be formatte
d |
| 98 [self testVariableName:@"var" type:@"ri" expectedResult:@"const int var"]; |
| 99 [self testVariableName:@"var" type:@"ni" expectedResult:@"in int var"]; |
| 100 [self testVariableName:@"var" type:@"Ni" expectedResult:@"inout int var"]; |
| 101 [self testVariableName:@"var" type:@"oi" expectedResult:@"out int var"]; |
| 102 [self testVariableName:@"var" type:@"Oi" expectedResult:@"bycopy int var"]; |
| 103 [self testVariableName:@"var" type:@"Ri" expectedResult:@"byref int var"]; |
| 104 [self testVariableName:@"var" type:@"Vi" expectedResult:@"oneway int var"]; |
| 105 |
| 106 [self testVariableName:@"var" type:@"^i" expectedResult:@"int *var"]; |
| 107 [self testVariableName:@"var" type:@"r^i" expectedResult:@"const int *var"]; |
| 108 [self testVariableName:nil type:@"r^i" expectedResult:@"const int *"]; |
| 109 //[self testVariableName:nil type:@"^ri" expectedResult:@"int *const"]; |
| 110 //[self testVariableName:nil type:@"r^ri" expectedResult:@"const int *const"
]; |
| 111 |
| 112 //[self testVariableName:nil type:@"i" expectedResult:@"int var-it went to t
he end"]; |
| 113 } |
| 114 |
| 115 - (void)testPointers; |
| 116 { |
| 117 [self testVariableName:@"var" type:@"^c" expectedResult:@"char *var"]; |
| 118 [self testVariableName:@"var" type:@"^i" expectedResult:@"int *var"]; |
| 119 [self testVariableName:@"var" type:@"^s" expectedResult:@"short *var"]; |
| 120 [self testVariableName:@"var" type:@"^l" expectedResult:@"long *var"]; |
| 121 [self testVariableName:@"var" type:@"^q" expectedResult:@"long long *var"]; |
| 122 [self testVariableName:@"var" type:@"^C" expectedResult:@"unsigned char *var
"]; |
| 123 [self testVariableName:@"var" type:@"^I" expectedResult:@"unsigned int *var"
]; |
| 124 [self testVariableName:@"var" type:@"^S" expectedResult:@"unsigned short *va
r"]; |
| 125 [self testVariableName:@"var" type:@"^L" expectedResult:@"unsigned long *var
"]; |
| 126 [self testVariableName:@"var" type:@"^Q" expectedResult:@"unsigned long long
*var"]; |
| 127 [self testVariableName:@"var" type:@"^f" expectedResult:@"float *var"]; |
| 128 [self testVariableName:@"var" type:@"^d" expectedResult:@"double *var"]; |
| 129 [self testVariableName:@"var" type:@"^B" expectedResult:@"_Bool *var"]; |
| 130 [self testVariableName:@"var" type:@"^v" expectedResult:@"void *var"]; |
| 131 [self testVariableName:@"var" type:@"^*" expectedResult:@"char **var"]; |
| 132 [self testVariableName:@"var" type:@"^#" expectedResult:@"Class *var"]; |
| 133 [self testVariableName:@"var" type:@"^:" expectedResult:@"SEL *var"]; |
| 134 [self testVariableName:@"var" type:@"^%" expectedResult:@"NXAtom *var"]; |
| 135 [self testVariableName:@"var" type:@"^?" expectedResult:@"void *var"]; |
| 136 |
| 137 [self testVariableName:@"var" type:@"^^i" expectedResult:@"int **var"]; |
| 138 } |
| 139 |
| 140 - (void)testBitfield; |
| 141 { |
| 142 [self testVariableName:@"var" type:@"b0" expectedResult:@"unsigned int var:0
"]; |
| 143 [self testVariableName:@"var" type:@"b1" expectedResult:@"unsigned int var:1
"]; |
| 144 [self testVariableName:@"var" type:@"b19" expectedResult:@"unsigned int var:
19"]; |
| 145 [self testVariableName:@"var" type:@"b31" expectedResult:@"unsigned int var:
31"]; |
| 146 [self testVariableName:@"var" type:@"b32" expectedResult:@"unsigned int var:
32"]; |
| 147 [self testVariableName:@"var" type:@"b33" expectedResult:@"unsigned int var:
33"]; |
| 148 [self testVariableName:@"var" type:@"b63" expectedResult:@"unsigned int var:
63"]; |
| 149 [self testVariableName:@"var" type:@"b64" expectedResult:@"unsigned int var:
64"]; |
| 150 [self testVariableName:@"var" type:@"b65" expectedResult:@"unsigned int var:
65"]; |
| 151 [self testVariableName:nil type:@"b3" expectedResult:@"unsigned int :3"]; |
| 152 |
| 153 [self testVariableName:@"var" type:@"b" expectedResult:@"unsigned int var:(n
ull)"]; // Don't we always expect a number? |
| 154 } |
| 155 |
| 156 - (void)testArrayType; |
| 157 { |
| 158 [self testVariableName:@"var" type:@"[0c]" expectedResult:@"char var[0]"]; |
| 159 [self testVariableName:@"var" type:@"[1c]" expectedResult:@"char var[1]"]; |
| 160 [self testVariableName:@"var" type:@"[16c]" expectedResult:@"char var[16]"]; |
| 161 |
| 162 [self testVariableName:@"var" type:@"[16^i]" expectedResult:@"int *var[16]"]
; |
| 163 [self testVariableName:@"var" type:@"^[16i]" expectedResult:@"int (*var)[16]
"]; |
| 164 [self testVariableName:@"var" type:@"[16^^i]" expectedResult:@"int **var[16]
"]; |
| 165 [self testVariableName:@"var" type:@"^^[16i]" expectedResult:@"int (**var)[1
6]"]; |
| 166 [self testVariableName:@"var" type:@"^[16^i]" expectedResult:@"int *(*var)[1
6]"]; |
| 167 |
| 168 [self testVariableName:@"var" type:@"[8[12f]]" expectedResult:@"float var[8]
[12]"]; |
| 169 //[self testVariableName:@"var" type:@"[8b3]" expectedResult:@"int var:3[8]"
]; // Don't know if this is even valid! |
| 170 } |
| 171 |
| 172 - (void)testStructType; |
| 173 { |
| 174 //[self testVariableName:@"var" type:@"{}" expectedResult:@""]; |
| 175 [self testVariableName:@"var" type:@"{?}" expectedResult:@"struct var"]; //
expected, but not correct. Test these in struct/union handling unit tests |
| 176 [self testVariableName:@"var" type:@"{NSStreamFunctions}" expectedResult:@"s
truct NSStreamFunctions var"]; |
| 177 [self testVariableName:@"var" type:@"{__ssFlags=\"delegateLearnsWords\"b1\"d
elegateForgetsWords\"b1\"busy\"b1\"_reserved\"b29}" expectedResult:@"struct __ss
Flags var"]; |
| 178 } |
| 179 |
| 180 - (void)testUnionType; |
| 181 { |
| 182 [self testVariableName:@"_tokenBuffer" type:@"(?=\"ascii\"*\"unicode\"^S)" e
xpectedResult:@"union _tokenBuffer"]; // expected, but not correct. Test these
in struct/union handling unit tests |
| 183 } |
| 184 |
| 185 // I have diagrams of these cases |
| 186 - (void)testDiagrammedTypes; |
| 187 { |
| 188 [self testVariableName:@"foo" type:@"i" expectedResult:@"int foo"]; |
| 189 [self testVariableName:@"foo" type:@"^i" expectedResult:@"int *foo"]; |
| 190 [self testVariableName:@"foo" type:@"^^i" expectedResult:@"int **foo"]; |
| 191 [self testVariableName:@"foo" type:@"[8i]" expectedResult:@"int foo[8]"]; |
| 192 [self testVariableName:@"foo" type:@"[8^i]" expectedResult:@"int *foo[8]"]; |
| 193 [self testVariableName:@"foo" type:@"^[8i]" expectedResult:@"int (*foo)[8]"]
; |
| 194 [self testVariableName:@"foo" type:@"[8[12i]]" expectedResult:@"int foo[8][1
2]"]; |
| 195 [self testVariableName:@"foo" type:@"^^[8i]" expectedResult:@"int (**foo)[8]
"]; |
| 196 [self testVariableName:@"foo" type:@"^^[8[12i]]" expectedResult:@"int (**foo
)[8][12]"]; |
| 197 [self testVariableName:@"foo" type:@"[3^^[8i]]" expectedResult:@"int (**foo[
3])[8]"]; |
| 198 [self testVariableName:@"foo" type:@"@" expectedResult:@"id foo"]; |
| 199 [self testVariableName:@"foo" type:@"@\"NSString\"" expectedResult:@"NSStrin
g *foo"]; |
| 200 [self testVariableName:@"foo" type:@"b7" expectedResult:@"unsigned int foo:7
"]; |
| 201 [self testVariableName:@"foo" type:@"r^i" expectedResult:@"const int *foo"]; |
| 202 //[self testVariableName:@"foo" type:@"" expectedResult:@""]; |
| 203 } |
| 204 |
| 205 - (void)testErrors; |
| 206 { |
| 207 [self testVariableName:@"bar" type:@"[5i" expectedResult:nil]; |
| 208 [self testVariableName:@"bar" type:@"" expectedResult:nil]; |
| 209 [self testVariableName:@"bar" type:nil expectedResult:nil]; |
| 210 } |
| 211 |
| 212 #if 0 |
| 213 - (void)testBar; |
| 214 { |
| 215 // Test for failure. |
| 216 [self testVariableName:@"var" type:@"i" expectedResult:@"float var"]; |
| 217 [self testVariableName:@"var" type:@"*" expectedResult:@"STR var"]; |
| 218 } |
| 219 #endif |
| 220 |
| 221 - (void)testEncoding; |
| 222 { |
| 223 [self parseAndEncodeType:@"c"]; |
| 224 [self parseAndEncodeType:@"i"]; |
| 225 [self parseAndEncodeType:@"s"]; |
| 226 [self parseAndEncodeType:@"l"]; |
| 227 [self parseAndEncodeType:@"q"]; |
| 228 [self parseAndEncodeType:@"C"]; |
| 229 [self parseAndEncodeType:@"I"]; |
| 230 [self parseAndEncodeType:@"S"]; |
| 231 [self parseAndEncodeType:@"L"]; |
| 232 [self parseAndEncodeType:@"Q"]; |
| 233 [self parseAndEncodeType:@"f"]; |
| 234 [self parseAndEncodeType:@"d"]; |
| 235 [self parseAndEncodeType:@"B"]; |
| 236 [self parseAndEncodeType:@"v"]; |
| 237 //[self parseAndEncodeType:@"*"]; |
| 238 [self parseAndEncodeType:@"#"]; |
| 239 [self parseAndEncodeType:@":"]; |
| 240 [self parseAndEncodeType:@"%"]; |
| 241 [self parseAndEncodeType:@"?"]; |
| 242 |
| 243 [self parseAndEncodeType:@"ri"]; |
| 244 [self parseAndEncodeType:@"ni"]; |
| 245 [self parseAndEncodeType:@"Ni"]; |
| 246 [self parseAndEncodeType:@"oi"]; |
| 247 [self parseAndEncodeType:@"Oi"]; |
| 248 [self parseAndEncodeType:@"Ri"]; |
| 249 [self parseAndEncodeType:@"Vi"]; |
| 250 |
| 251 [self parseAndEncodeType:@"^i"]; |
| 252 [self parseAndEncodeType:@"r^i"]; |
| 253 |
| 254 [self parseAndEncodeType:@"^c"]; |
| 255 [self parseAndEncodeType:@"^i"]; |
| 256 [self parseAndEncodeType:@"^s"]; |
| 257 [self parseAndEncodeType:@"^l"]; |
| 258 [self parseAndEncodeType:@"^q"]; |
| 259 [self parseAndEncodeType:@"^C"]; |
| 260 [self parseAndEncodeType:@"^I"]; |
| 261 [self parseAndEncodeType:@"^S"]; |
| 262 [self parseAndEncodeType:@"^L"]; |
| 263 [self parseAndEncodeType:@"^Q"]; |
| 264 [self parseAndEncodeType:@"^f"]; |
| 265 [self parseAndEncodeType:@"^d"]; |
| 266 [self parseAndEncodeType:@"^B"]; |
| 267 [self parseAndEncodeType:@"^v"]; |
| 268 //[self parseAndEncodeType:@"^*"]; |
| 269 [self parseAndEncodeType:@"^#"]; |
| 270 [self parseAndEncodeType:@"^:"]; |
| 271 [self parseAndEncodeType:@"^%"]; |
| 272 [self parseAndEncodeType:@"^?"]; |
| 273 |
| 274 [self parseAndEncodeType:@"^^i"]; |
| 275 [self parseAndEncodeType:@"b0"]; |
| 276 [self parseAndEncodeType:@"b1"]; |
| 277 //[self parseAndEncodeType:@"b"]; |
| 278 |
| 279 [self parseAndEncodeType:@"[0c]"]; |
| 280 [self parseAndEncodeType:@"[16c]"]; |
| 281 [self parseAndEncodeType:@"[16^i]"]; |
| 282 [self parseAndEncodeType:@"^[16i]"]; |
| 283 [self parseAndEncodeType:@"[16^^i]"]; |
| 284 [self parseAndEncodeType:@"^^[16i]"]; |
| 285 [self parseAndEncodeType:@"^[16^i]"]; |
| 286 [self parseAndEncodeType:@"[8[12f]]"]; |
| 287 |
| 288 [self parseAndEncodeType:@"{?}"]; |
| 289 [self parseAndEncodeType:@"{NSStreamFunctions}"]; |
| 290 [self parseAndEncodeType:@"{__ssFlags=\"delegateLearnsWords\"b1\"delegateFor
getsWords\"b1\"busy\"b1\"_reserved\"b29}"]; |
| 291 [self parseAndEncodeType:@"(?=\"ascii\"^s\"unicode\"^S)"]; |
| 292 |
| 293 [self parseAndEncodeType:@"i"]; |
| 294 [self parseAndEncodeType:@"^i"]; |
| 295 [self parseAndEncodeType:@"^^i"]; |
| 296 [self parseAndEncodeType:@"[8i]"]; |
| 297 [self parseAndEncodeType:@"[8^i]"]; |
| 298 [self parseAndEncodeType:@"^[8i]"]; |
| 299 [self parseAndEncodeType:@"[8[12i]]"]; |
| 300 [self parseAndEncodeType:@"^^[8i]"]; |
| 301 [self parseAndEncodeType:@"^^[8[12i]]"]; |
| 302 [self parseAndEncodeType:@"[3^^[8i]]"]; |
| 303 [self parseAndEncodeType:@"@"]; |
| 304 [self parseAndEncodeType:@"@\"NSString\""]; |
| 305 [self parseAndEncodeType:@"b7"]; |
| 306 [self parseAndEncodeType:@"r^i"]; |
| 307 |
| 308 //[self parseAndEncodeType:@""]; |
| 309 } |
| 310 |
| 311 - (void)testTemplateTypes; |
| 312 { |
| 313 [self testVariableName:@"var" type:@"r" expectedResult:@"const var"]; |
| 314 |
| 315 [self testVariableName:@"var" type:@"{KWQRefPtr<KWQValueListImpl::KWQValueLi
stPrivate>=^{KWQValueListPrivate}}" |
| 316 expectedResult:@"struct KWQRefPtr<KWQValueListImpl::KWQValueListPrivat
e> var"]; |
| 317 |
| 318 [self testVariableName:@"var" type:@"{QValueList<foo<bar>,foo<baz>,bar<blegg
a>>=i}" |
| 319 expectedResult:@"struct QValueList<foo<bar>, foo<baz>, bar<blegga>> va
r"]; |
| 320 [self testVariableName:@"var" type:@"{QValueList<KWQSlot<foobar>>=i}" expect
edResult:@"struct QValueList<KWQSlot<foobar>> var"]; |
| 321 [self testVariableName:@"var" type:@"{QValueList<KWQSlot>=i}" expectedResult
:@"struct QValueList<KWQSlot> var"]; |
| 322 [self testVariableName:@"var" |
| 323 type:@"{QValueList<KWQSlot>={KWQValueListImpl={KWQRefPtr<KWQValueListI
mpl::KWQValueListPrivate>=^{KWQValueListPrivate}}}}" |
| 324 expectedResult:@"struct QValueList<KWQSlot> var"]; |
| 325 [self testVariableName:@"var" type:@"{KWQSignal=^{QObject}^{KWQSignal}*{QVal
ueList<KWQSlot>={KWQValueListImpl={KWQRefPtr<KWQValueListImpl::KWQValueListPriva
te>=^{KWQValueListPrivate}}}}}" expectedResult:@"struct KWQSignal var"]; |
| 326 [self testVariableName:@"var" type:@"^{QButton={KWQSignal=^{QObject}^{KWQSig
nal}*{QValueList<KWQSlot>={KWQValueListImpl={KWQRefPtr<KWQValueListImpl::KWQValu
eListPrivate>=^{KWQValueListPrivate}}}}}}" expectedResult:@"struct QButton *var"
]; |
| 327 |
| 328 [self testVariableName:@"var" type:@"{std::pair<const double, int>=i}" expec
tedResult:@"struct std::pair<const double, int> var"]; |
| 329 } |
| 330 |
| 331 - (void)testIdProtocolTypes; |
| 332 { |
| 333 [self testVariableName:@"var" type:@"@" expectedResult:@"id var"]; |
| 334 [self testVariableName:@"var" type:@"@\"NSObject\"" expectedResult:@"NSObjec
t *var"]; |
| 335 [self testVariableName:@"var" type:@"@\"<MyProtocol>\"" expectedResult:@"id
<MyProtocol> var"]; |
| 336 [self testVariableName:@"var" type:@"@\"<MyProtocol1,MyProtocol2>\"" expecte
dResult:@"id <MyProtocol1, MyProtocol2> var"]; |
| 337 } |
| 338 |
| 339 - (void)testPages08; |
| 340 { |
| 341 // Pages '08 has this bit in it: {vector<<unnamed>::AnimationChunk,std::allo
cator<<unnamed>::AnimationChunk> >=II} |
| 342 |
| 343 [self testVariableName:@"var" type:@"{unnamed=II}" expectedResult:@"struct u
nnamed var"]; |
| 344 [self testVariableName:@"var" type:@"{vector<unnamed>=II}" expectedResult:@"
struct vector<unnamed> var"]; |
| 345 [self testVariableName:@"var" type:@"{vector<unnamed::blegga>=II}" expectedR
esult:@"struct vector<unnamed::blegga> var"]; |
| 346 [self testVariableName:@"var" type:@"{vector<<unnamed>::blegga>=II}" expecte
dResult:@"struct vector<unnamed::blegga> var"]; |
| 347 [self testVariableName:@"var" type:@"{vector<<unnamed>::AnimationChunk>=II}"
expectedResult:@"struct vector<unnamed::AnimationChunk> var"]; |
| 348 [self testVariableName:@"var" type:@"{vector<<unnamed>::AnimationChunk,std::
allocator<<unnamed>::AnimationChunk> >=II}" |
| 349 expectedResult:@"struct vector<unnamed::AnimationChunk, std::allocator
<unnamed::AnimationChunk>> var"]; |
| 350 } |
| 351 |
| 352 |
| 353 @end |
OLD | NEW |