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 "CDMultiFileVisitor.h" |
| 7 |
| 8 #import "NSArray-Extensions.h" |
| 9 #import "CDClassDump.h" |
| 10 #import "CDClassFrameworkVisitor.h" |
| 11 #import "CDSymbolReferences.h" |
| 12 #import "CDOCClass.h" |
| 13 #import "CDOCProtocol.h" |
| 14 #import "CDOCIvar.h" |
| 15 #import "CDTypeController.h" |
| 16 |
| 17 @implementation CDMultiFileVisitor |
| 18 |
| 19 - (id)init; |
| 20 { |
| 21 if ([super init] == nil) |
| 22 return nil; |
| 23 |
| 24 outputPath = nil; |
| 25 |
| 26 return self; |
| 27 } |
| 28 |
| 29 - (void)dealloc; |
| 30 { |
| 31 [outputPath release]; |
| 32 |
| 33 [super dealloc]; |
| 34 } |
| 35 |
| 36 - (NSString *)outputPath; |
| 37 { |
| 38 return outputPath; |
| 39 } |
| 40 |
| 41 - (void)setOutputPath:(NSString *)newOutputPath; |
| 42 { |
| 43 if (newOutputPath == outputPath) |
| 44 return; |
| 45 |
| 46 [outputPath release]; |
| 47 outputPath = [newOutputPath retain]; |
| 48 } |
| 49 |
| 50 - (void)createOutputPathIfNecessary; |
| 51 { |
| 52 if (outputPath != nil) { |
| 53 NSFileManager *fileManager; |
| 54 BOOL isDirectory; |
| 55 |
| 56 fileManager = [NSFileManager defaultManager]; |
| 57 if ([fileManager fileExistsAtPath:outputPath isDirectory:&isDirectory] =
= NO) { |
| 58 BOOL result; |
| 59 |
| 60 result = [fileManager createDirectoryAtPath:outputPath attributes:ni
l]; |
| 61 if (result == NO) { |
| 62 NSLog(@"Error: Couldn't create output directory: %@", outputPath
); |
| 63 return; |
| 64 } |
| 65 } else if (isDirectory == NO) { |
| 66 NSLog(@"Error: File exists at output path: %@", outputPath); |
| 67 return; |
| 68 } |
| 69 } |
| 70 } |
| 71 |
| 72 - (void)buildClassFrameworks; |
| 73 { |
| 74 CDClassFrameworkVisitor *visitor; |
| 75 |
| 76 visitor = [[CDClassFrameworkVisitor alloc] init]; |
| 77 [visitor setClassDump:classDump]; |
| 78 [classDump recursivelyVisit:visitor]; |
| 79 [symbolReferences setFrameworkNamesByClassName:[visitor frameworkNamesByClas
sName]]; |
| 80 [symbolReferences setFrameworkNamesByProtocolName:[visitor frameworkNamesByP
rotocolName]]; |
| 81 [visitor release]; |
| 82 } |
| 83 |
| 84 - (void)generateStructureHeader; |
| 85 { |
| 86 NSString *filename; |
| 87 NSString *referenceString; |
| 88 |
| 89 [resultString setString:@""]; |
| 90 [classDump appendHeaderToString:resultString]; |
| 91 |
| 92 [symbolReferences removeAllReferences]; |
| 93 referenceIndex = [resultString length]; |
| 94 |
| 95 [[classDump typeController] appendStructuresToString:resultString symbolRefe
rences:symbolReferences]; |
| 96 |
| 97 referenceString = [symbolReferences referenceString]; |
| 98 if (referenceString != nil) |
| 99 [resultString insertString:referenceString atIndex:referenceIndex]; |
| 100 |
| 101 filename = @"CDStructures.h"; |
| 102 if (outputPath != nil) |
| 103 filename = [outputPath stringByAppendingPathComponent:filename]; |
| 104 |
| 105 [[resultString dataUsingEncoding:NSUTF8StringEncoding] writeToFile:filename
atomically:YES]; |
| 106 } |
| 107 |
| 108 - (void)willBeginVisiting; |
| 109 { |
| 110 [super willBeginVisiting]; |
| 111 |
| 112 [classDump appendHeaderToString:resultString]; |
| 113 |
| 114 if ([classDump containsObjectiveCData] || [classDump hasEncryptedFiles]) { |
| 115 [self buildClassFrameworks]; |
| 116 [self createOutputPathIfNecessary]; |
| 117 [self generateStructureHeader]; |
| 118 } else { |
| 119 // TODO (2007-06-14): Make sure this generates no output files in this c
ase. |
| 120 NSLog(@"Warning: This file does not contain any Objective-C runtime info
rmation."); |
| 121 } |
| 122 } |
| 123 |
| 124 - (void)willVisitClass:(CDOCClass *)aClass; |
| 125 { |
| 126 NSString *str; |
| 127 |
| 128 // First, we set up some context... |
| 129 [resultString setString:@""]; |
| 130 [classDump appendHeaderToString:resultString]; |
| 131 |
| 132 [symbolReferences removeAllReferences]; |
| 133 str = [symbolReferences importStringForClassName:[aClass superClassName]]; |
| 134 if (str != nil) { |
| 135 [resultString appendString:str]; |
| 136 [resultString appendString:@"\n"]; |
| 137 } |
| 138 |
| 139 referenceIndex = [resultString length]; |
| 140 |
| 141 // And then generate the regular output |
| 142 [super willVisitClass:aClass]; |
| 143 } |
| 144 |
| 145 - (void)didVisitClass:(CDOCClass *)aClass; |
| 146 { |
| 147 NSString *referenceString; |
| 148 NSString *filename; |
| 149 |
| 150 // Generate the regular output |
| 151 [super didVisitClass:aClass]; |
| 152 |
| 153 // Then insert the imports and write the file. |
| 154 [symbolReferences removeClassName:[aClass name]]; |
| 155 [symbolReferences removeClassName:[aClass superClassName]]; |
| 156 referenceString = [symbolReferences referenceString]; |
| 157 if (referenceString != nil) |
| 158 [resultString insertString:referenceString atIndex:referenceIndex]; |
| 159 |
| 160 filename = [NSString stringWithFormat:@"%@.h", [aClass name]]; |
| 161 if (outputPath != nil) |
| 162 filename = [outputPath stringByAppendingPathComponent:filename]; |
| 163 |
| 164 [[resultString dataUsingEncoding:NSUTF8StringEncoding] writeToFile:filename
atomically:YES]; |
| 165 } |
| 166 |
| 167 - (void)willVisitCategory:(CDOCCategory *)aCategory; |
| 168 { |
| 169 NSString *str; |
| 170 |
| 171 // First, we set up some context... |
| 172 [resultString setString:@""]; |
| 173 [classDump appendHeaderToString:resultString]; |
| 174 |
| 175 [symbolReferences removeAllReferences]; |
| 176 str = [symbolReferences importStringForClassName:[aCategory className]]; |
| 177 if (str != nil) { |
| 178 [resultString appendString:str]; |
| 179 [resultString appendString:@"\n"]; |
| 180 } |
| 181 referenceIndex = [resultString length]; |
| 182 |
| 183 // And then generate the regular output |
| 184 [super willVisitCategory:aCategory]; |
| 185 } |
| 186 |
| 187 - (void)didVisitCategory:(CDOCCategory *)aCategory; |
| 188 { |
| 189 NSString *referenceString; |
| 190 NSString *filename; |
| 191 |
| 192 // Generate the regular output |
| 193 [super didVisitCategory:aCategory]; |
| 194 |
| 195 // Then insert the imports and write the file. |
| 196 [symbolReferences removeClassName:[aCategory className]]; |
| 197 referenceString = [symbolReferences referenceString]; |
| 198 if (referenceString != nil) |
| 199 [resultString insertString:referenceString atIndex:referenceIndex]; |
| 200 |
| 201 filename = [NSString stringWithFormat:@"%@-%@.h", [aCategory className], [aC
ategory name]]; |
| 202 if (outputPath != nil) |
| 203 filename = [outputPath stringByAppendingPathComponent:filename]; |
| 204 |
| 205 [[resultString dataUsingEncoding:NSUTF8StringEncoding] writeToFile:filename
atomically:YES]; |
| 206 } |
| 207 |
| 208 - (void)willVisitProtocol:(CDOCProtocol *)aProtocol; |
| 209 { |
| 210 [resultString setString:@""]; |
| 211 [classDump appendHeaderToString:resultString]; |
| 212 |
| 213 [symbolReferences removeAllReferences]; |
| 214 referenceIndex = [resultString length]; |
| 215 |
| 216 // And then generate the regular output |
| 217 [super willVisitProtocol:aProtocol]; |
| 218 } |
| 219 |
| 220 - (void)didVisitProtocol:(CDOCProtocol *)aProtocol; |
| 221 { |
| 222 NSString *referenceString; |
| 223 NSString *filename; |
| 224 |
| 225 // Generate the regular output |
| 226 [super didVisitProtocol:aProtocol]; |
| 227 |
| 228 // Then insert the imports and write the file. |
| 229 referenceString = [symbolReferences referenceString]; |
| 230 if (referenceString != nil) |
| 231 [resultString insertString:referenceString atIndex:referenceIndex]; |
| 232 |
| 233 filename = [NSString stringWithFormat:@"%@-Protocol.h", [aProtocol name]]; |
| 234 if (outputPath != nil) |
| 235 filename = [outputPath stringByAppendingPathComponent:filename]; |
| 236 |
| 237 [[resultString dataUsingEncoding:NSUTF8StringEncoding] writeToFile:filename
atomically:YES]; |
| 238 } |
| 239 |
| 240 @end |
OLD | NEW |