diff --git a/Tools/xcodecapp-cocoa/FSEventCallback.m b/Tools/xcodecapp-cocoa/FSEventCallback.m index 23b4b9248..78a7387fd 100644 --- a/Tools/xcodecapp-cocoa/FSEventCallback.m +++ b/Tools/xcodecapp-cocoa/FSEventCallback.m @@ -36,7 +36,7 @@ void fsevents_callback(ConstFSEventStreamRef streamRef, for (i = 0; i < numEvents; i++) { - NSString *path = [(NSArray *)eventPaths objectAtIndex:i]; + NSString *path = [[(NSArray *)eventPaths objectAtIndex:i] stringByStandardizingPath]; if (useFileBasedListening) { @@ -55,27 +55,35 @@ void fsevents_callback(ConstFSEventStreamRef streamRef, else { NSArray *subpaths = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:NULL]; - + + // Uncomment to test under 10.7 + // BOOL isDir; + // [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDir]; + // if (!isDir) + // continue; + + [xcc tidyShadowedFiles:path]; + for (NSString *subpath in subpaths) - { - NSString *fullPath = [NSString stringWithFormat:@"%@%@", path, subpath]; + { + NSString *fullPath = [[NSString stringWithFormat:@"%@/%@", path, subpath] stringByStandardizingPath]; if ([xcc isPathMatchingIgnoredPaths:fullPath] || (![xcc isXIBFile:fullPath] && ![xcc isObjJFile:fullPath] && ![xcc isXCCIgnoreFile:fullPath])) continue; - NSDate *lastModifiedDate = [xcc lastModificationDateForPath:subpath]; + NSDate *lastModifiedDate = [xcc lastModificationDateForPath:fullPath]; NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:fullPath error:nil]; NSDate *fileModDate = [fileAttributes objectForKey:NSFileModificationDate]; - + if ([fileModDate compare:lastModifiedDate] == NSOrderedDescending) { - [xcc updateLastModificationDate:fileModDate forPath:subpath]; + [xcc updateLastModificationDate:fileModDate forPath:fullPath]; [xcc handleFileModification:fullPath notify:YES]; } } } - + [xcc updateLastEventId:eventIds[i]]; } } diff --git a/Tools/xcodecapp-cocoa/TNXCodeCapp.h b/Tools/xcodecapp-cocoa/TNXCodeCapp.h index e2aac92a2..0f9bb7297 100644 --- a/Tools/xcodecapp-cocoa/TNXCodeCapp.h +++ b/Tools/xcodecapp-cocoa/TNXCodeCapp.h @@ -75,10 +75,13 @@ extern NSString * const XCCListeningStartNotification; @end + @interface TNXCodeCapp (SnowLeopard) - (void)updateLastModificationDate:(NSDate *)date forPath:(NSString *)path; - (NSDate*)lastModificationDateForPath:(NSString *)path; +- (NSString *)unshadowURLForString:(NSString *)aString; +- (void)tidyShadowedFiles:(NSString*)basePath; @end diff --git a/Tools/xcodecapp-cocoa/TNXCodeCapp.m b/Tools/xcodecapp-cocoa/TNXCodeCapp.m index 10f3c941f..24f2d3a91 100644 --- a/Tools/xcodecapp-cocoa/TNXCodeCapp.m +++ b/Tools/xcodecapp-cocoa/TNXCodeCapp.m @@ -56,7 +56,9 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification Gestalt(gestaltSystemVersionMinor, &versionMinor); supportsFileBasedListening = versionMajor >= 10 && versionMinor >= 7; - + // Uncomment to test under 10.7 + // supportsFileBasedListening = NO; + if (supportsFileBasedListening) DLog(@"using 10.7+ mode listening (clean)"); else @@ -544,7 +546,11 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification pathModificationDates = [NSMutableDictionary new]; } - [pathModificationDates setObject:[date retain] forKey:path]; + if (date) + [pathModificationDates setObject:[date retain] forKey:path]; + else + [pathModificationDates removeObjectForKey:path]; + [[NSUserDefaults standardUserDefaults] setObject:pathModificationDates forKey:@"pathModificationDates"]; } @@ -564,4 +570,38 @@ NSString * const XCCListeningStartNotification = @"XCCListeningStartNotification return appStartedTimestamp; } +- (NSString *)unshadowURLForString:(NSString *)aString +{ + NSMutableString * unshadowedPath = [NSMutableString stringWithString:aString]; + + [unshadowedPath replaceOccurrencesOfString:@"_" + withString:@"/" + options:NSCaseInsensitiveSearch + range:NSMakeRange(0, [unshadowedPath length])]; + + [unshadowedPath replaceOccurrencesOfString:@".h" + withString:@".j" + options:NSCaseInsensitiveSearch + range:NSMakeRange(0, [unshadowedPath length])]; + + return [NSString stringWithString:unshadowedPath]; +} + +- (void)tidyShadowedFiles:(NSString*)basePath +{ + NSArray *subpaths = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[XCodeSupportProjectSources path] error:NULL]; + + for (NSString *subpath in subpaths) + { + NSString *unshadowed = [self unshadowURLForString:subpath]; + NSString *shadowFullPath = [NSString stringWithFormat:@"%@/%@", [XCodeSupportProjectSources path], subpath]; + if (![fm fileExistsAtPath:unshadowed]) + { + DLog(@"cleaning shadow file: %@", subpath); + [fm removeItemAtPath:shadowFullPath error:nil]; + [self updateLastModificationDate:nil forPath:unshadowed]; + } + } +} + @end