50#if OO_OXP_VERIFIER_ENABLED
59static BOOL
CheckNameConflict(NSString *lcName, NSDictionary *directoryCases, NSDictionary *rootFiles, NSString **outExisting, NSString **outExistingType);
62@interface OOFileScannerVerifierStage (OOPrivate)
76- (NSDictionary *)lowercaseMap:(NSArray *)array;
78- (NSDictionary *)scanDirectory:(NSString *)path;
79- (void)checkPListFormat:(NSPropertyListFormat)format file:(NSString *)file folder:(NSString *)folder;
91 [_caseWarnings release];
92 [_directoryListings release];
93 [_directoryCases release];
108 NSAutoreleasePool *pool =
nil;
139- (BOOL)fileExists:(NSString *)file
140 inFolder:(NSString *)folder
141 referencedFrom:(NSString *)context
142 checkBuiltIn:(BOOL)checkBuiltIn
139- (BOOL)fileExists:(NSString *)file {
…}
148- (NSString *)pathForFile:(NSString *)file
149 inFolder:(NSString *)folder
150 referencedFrom:(NSString *)context
151 checkBuiltIn:(BOOL)checkBuiltIn
153 NSString *lcName =
nil,
160 if (file ==
nil)
return nil;
161 lcName = [
file lowercaseString];
165 lcDirName = [
folder lowercaseString];
166 realFileName = [[_directoryListings oo_dictionaryForKey:lcDirName] objectForKey:lcName];
168 if (realFileName !=
nil)
170 realDirName = [_directoryCases objectForKey:lcDirName];
171 path = [
realDirName stringByAppendingPathComponent:realFileName];
177 realFileName = [[_directoryListings oo_dictionaryForKey:@""] objectForKey:lcName];
179 if (realFileName !=
nil)
187 [_usedFiles addObject:path];
188 if (realDirName !=
nil && ![realDirName isEqual:folder])
193 [_caseWarnings addObject:lcDirName];
194 OOLog(
@"verifyOXP.files.caseMismatch",
@"***** ERROR: case mismatch: directory '%@' should be called '%@'.", realDirName, folder);
198 if (![realFileName isEqual:file])
203 [_caseWarnings addObject:lcName];
210 OOLog(
@"verifyOXP.files.caseMismatch",
@"***** ERROR: case mismatch: request for file '%@'%@ resolved to '%@'.", expectedPath, context, path);
214 return [_basePath stringByAppendingPathComponent:path];
148- (NSString *)pathForFile:(NSString *)file {
…}
225- (NSData *)dataForFile:(NSString *)file
226 inFolder:(NSString *)folder
227 referencedFrom:(NSString *)context
228 checkBuiltIn:(BOOL)checkBuiltIn
230 NSString *path =
nil;
233 if (path ==
nil)
return nil;
235 return [
NSData dataWithContentsOfMappedFile:path];
225- (NSData *)dataForFile:(NSString *)file {
…}
239- (id)plistNamed:(NSString *)file
240 inFolder:(NSString *)folder
241 referencedFrom:(NSString *)context
242 checkBuiltIn:(BOOL)checkBuiltIn
245 NSString *errorString =
nil;
246 NSPropertyListFormat format;
248 NSArray *errorLines =
nil;
249 NSEnumerator *errLineEnum =
nil;
250 NSString *displayName =
nil,
252 NSAutoreleasePool *pool =
nil;
255 if (data ==
nil)
return nil;
260 mutabilityOption:NSPropertyListImmutable
262 errorDescription:&errorString];
264#if OOLITE_RELEASE_PLIST_ERROR_STRINGS
283 [_badPLists addObject:errorKey];
284 OOLog(
@"verifyOXP.plist.parseError",
@"Could not interpret property list %@.", displayName);
286 errorLines = [
errorString componentsSeparatedByString:@"\n"];
287 for (errLineEnum = [errorLines objectEnumerator]; (errorString = [
errLineEnum nextObject]); )
289 while ([errorString hasPrefix:
@"\t"])
293 OOLog(
@"verifyOXP.plist.parseError",
@"%@", errorString);
302 return [
plist autorelease];
239- (id)plistNamed:(NSString *)file {
…}
306- (id)displayNameForFile:(NSString *)file andFolder:(NSString *)folder
308 if (file !=
nil && folder !=
nil)
return [
folder stringByAppendingPathComponent:file];
306- (id)displayNameForFile:(NSString *)file andFolder:(NSString *)folder {
…}
313- (NSArray *)filesInFolder:(NSString *)folder
315 if (folder ==
nil)
return nil;
316 return [[_directoryListings objectForKey:[
folder lowercaseString]] allValues];
313- (NSArray *)filesInFolder:(NSString *)folder {
…}
322@implementation OOFileScannerVerifierStage (OOPrivate)
326 NSDirectoryEnumerator *dirEnum =
nil;
327 NSString *name =
nil,
333 NSMutableDictionary *directoryListings =
nil,
334 *directoryCases =
nil,
336 NSDictionary *dirFiles =
nil;
337 NSSet *readMeNames =
nil;
349 dirEnum = [[
NSFileManager defaultManager] enumeratorAtPath:_basePath];
350 while ((name = [dirEnum nextObject]))
352 path = [
_basePath stringByAppendingPathComponent:name];
353 type = [[
dirEnum fileAttributes] fileType];
354 lcName = [
name lowercaseString];
356 if ([type isEqualToString:NSFileTypeDirectory])
360 if ([_skipDirectoryNames containsObject:name])
363 OOLog(
@"verifyOXP.verbose.listFiles",
@"- Skipping %@/", name);
365 else if (!
CheckNameConflict(lcName, directoryCases, rootFiles, &existing, &existingType))
367 OOLog(
@"verifyOXP.verbose.listFiles",
@"- %@/", name);
376 OOLog(
@"verifyOXP.scanFiles.overloadedName",
@"***** ERROR: %@ '%@' conflicts with %@ named '%@', ignoring. (OXPs must work on case-insensitive file systems!)",
@"directory", name, existingType, existing);
379 else if ([type isEqualToString:NSFileTypeRegular])
381 if ([_junkFileNames containsObject:name])
383 OOLog(
@"verifyOXP.scanFiles.skipJunk",
@"NOTE: skipping junk file %@.", name);
385 else if ([readMeNames containsObject:lcName])
387 OOLog(
@"verifyOXP.scanFiles.readMe",
@"----- WARNING: apparent Read Me file (\"%@\
") inside OXP. This is the wrong place for a Read Me file, because it will not be read.", name);
389 else if (!
CheckNameConflict(lcName, directoryCases, rootFiles, &existing, &existingType))
391 OOLog(
@"verifyOXP.verbose.listFiles",
@"- %@", name);
392 [
rootFiles setObject:name forKey:lcName];
396 OOLog(
@"verifyOXP.scanFiles.overloadedName",
@"***** ERROR: %@ '%@' conflicts with %@ named '%@', ignoring. (OXPs must work on case-insensitive file systems!)",
@"file", name, existingType, existing);
399 else if ([type isEqualToString:NSFileTypeSymbolicLink])
401 OOLog(
@"verifyOXP.scanFiles.symLink",
@"----- WARNING: \"%@\
" is a symbolic link, ignoring.", name);
405 OOLog(
@"verifyOXP.scanFiles.nonStandardFile",
@"----- WARNING: \"%@\
" is a non-standard file (%@), ignoring.", name, type);
409 _junkFileNames =
nil;
410 _skipDirectoryNames =
nil;
420 NSArray *knownNames =
nil;
421 NSEnumerator *nameEnum =
nil;
422 NSString *name =
nil;
423 NSString *lcName =
nil;
424 NSString *actual =
nil;
427 for (nameEnum = [knownNames objectEnumerator]; (name = [
nameEnum nextObject]); )
429 if (![name isKindOfClass:[NSString
class]])
continue;
431 lcName = [
name lowercaseString];
433 if (actual ==
nil)
continue;
435 if (![actual isEqualToString:name])
437 OOLog(
@"verifyOXP.files.caseMismatch",
@"***** ERROR: case mismatch: directory '%@' should be called '%@'.", actual, name);
446 NSArray *knownNames =
nil;
447 NSEnumerator *nameEnum =
nil;
448 NSString *name =
nil,
454 for (nameEnum = [knownNames objectEnumerator]; (name = [
nameEnum nextObject]); )
456 if (![name isKindOfClass:[NSString
class]])
continue;
462 lcName = [
name lowercaseString];
463 realFileName = [[
_directoryListings oo_dictionaryForKey:@"config"] objectForKey:lcName];
464 inConfigDir = realFileName !=
nil;
465 if (!inConfigDir) realFileName = [[
_directoryListings oo_dictionaryForKey:@""] objectForKey:lcName];
466 if (realFileName ==
nil)
continue;
468 if (![realFileName isEqualToString:name])
471 OOLog(
@"verifyOXP.files.caseMismatch",
@"***** ERROR: case mismatch: configuration file '%@' should be called '%@'.", realFileName, name);
479 NSDictionary *directories =
nil;
480 NSEnumerator *directoryEnum =
nil;
481 NSString *directory =
nil,
483 NSArray *fileList =
nil;
484 NSEnumerator *nameEnum =
nil;
485 NSString *name =
nil,
491 for (directoryEnum = [directories keyEnumerator]; (directory = [
directoryEnum nextObject]); )
494 lcDirectory = [
directory lowercaseString];
495 for (nameEnum = [fileList objectEnumerator]; (name = [
nameEnum nextObject]); )
497 if (![name isKindOfClass:[NSString
class]])
continue;
503 lcName = [
name lowercaseString];
504 realFileName = [[
_directoryListings oo_dictionaryForKey:lcDirectory] objectForKey:lcName];
505 inDirectory = (realFileName !=
nil);
511 if (realFileName ==
nil)
continue;
513 if (![realFileName isEqualToString:name])
515 if (inDirectory) realFileName = [
directory stringByAppendingPathComponent:realFileName];
516 OOLog(
@"verifyOXP.files.caseMismatch",
@"***** ERROR: case mismatch: file '%@' should be called '%@'.", realFileName, name);
523- (NSDictionary *)lowercaseMap:(NSArray *)array
526 NSString *canonical =
nil,
528 NSMutableDictionary *result =
nil;
534 for (i = 0; i !=
count; ++i)
536 canonical = [
array oo_stringAtIndex:i];
537 if (canonical !=
nil)
540 [
result setObject:canonical forKey:lowercase];
523- (NSDictionary *)lowercaseMap:(NSArray *)array {
…}
548- (NSDictionary *)scanDirectory:(NSString *)path
550 NSDirectoryEnumerator *dirEnum =
nil;
551 NSMutableDictionary *result =
nil;
552 NSString *name =
nil,
560 dirName = [
path lastPathComponent];
562 dirEnum = [[
NSFileManager defaultManager] enumeratorAtPath:path];
563 while ((name = [dirEnum nextObject]))
565 type = [[
dirEnum fileAttributes] fileType];
566 relativeName = [
dirName stringByAppendingPathComponent:name];
568 if ([_junkFileNames containsObject:name])
570 OOLog(
@"verifyOXP.scanFiles.skipJunk",
@"NOTE: skipping junk file %@/%@.", dirName, name);
572 else if ([type isEqualToString:NSFileTypeRegular])
574 lcName = [
name lowercaseString];
575 existing = [
result objectForKey:lcName];
579 OOLog(
@"verifyOXP.verbose.listFiles",
@"- %@", name);
580 [
result setObject:name forKey:lcName];
584 OOLog(
@"verifyOXP.scanFiles.overloadedName",
@"***** ERROR: %@ '%@' conflicts with %@ named '%@', ignoring. (OXPs must work on case-insensitive file systems!)",
@"file", relativeName,
@"file", [dirName stringByAppendingPathComponent:existing]);
589 if ([type isEqualToString:NSFileTypeDirectory])
592 if (![_skipDirectoryNames containsObject:name])
594 OOLog(
@"verifyOXP.scanFiles.directory",
@"----- WARNING: \"%@\
" is a nested directory, ignoring.", relativeName);
598 OOLog(
@"verifyOXP.verbose.listFiles",
@"- Skipping %@/%@/", dirName, name);
601 else if ([type isEqualToString:NSFileTypeSymbolicLink])
603 OOLog(
@"verifyOXP.scanFiles.symLink",
@"----- WARNING: \"%@\
" is a symbolic link, ignoring.", relativeName);
607 OOLog(
@"verifyOXP.scanFiles.nonStandardFile",
@"----- WARNING: \"%@\
" is a non-standard file (%@), ignoring.", relativeName, type);
548- (NSDictionary *)scanDirectory:(NSString *)path {
…}
616- (void)checkPListFormat:(NSPropertyListFormat)format file:(NSString *)file folder:(NSString *)folder
618 NSString *weirdnessKey =
nil;
619 NSString *formatDesc =
nil;
620 NSString *displayPath =
nil;
622 if (format != NSPropertyListOpenStepFormat && format != NSPropertyListXMLFormat_v1_0)
627 if (![_badPLists containsObject:weirdnessKey])
634 case NSPropertyListBinaryFormat_v1_0:
635 formatDesc =
@"Apple binary format";
639 case NSPropertyListGNUstepFormat:
640 formatDesc =
@"GNUstep text format";
643 case NSPropertyListGNUstepBinaryFormat:
644 formatDesc =
@"GNUstep binary format";
649 formatDesc = [
NSString stringWithFormat:@"unknown format (%i)", (int)format];
652 OOLog(
@"verifyOXP.plist.weirdFormat",
@"----- WARNING: Property list %@ is in %@; OpenStep text format and XML format are the recommended formats for Oolite.", displayPath, formatDesc);
616- (void)checkPListFormat:(NSPropertyListFormat)format file:(NSString *)file folder:(NSString *)folder {
…}
660 NSDictionary *dict =
nil;
661 NSArray *stems =
nil,
663 NSMutableSet *result =
nil;
664 NSUInteger i, j, stemCount, extCount;
665 NSString *stem =
nil,
669 stems = [
dict oo_arrayForKey:@"stems"];
670 extensions = [
dict oo_arrayForKey:@"extensions"];
671 stemCount = [
stems count];
673 if (stemCount * extCount == 0)
return nil;
676 result = [
NSMutableSet setWithCapacity:stemCount * extCount];
677 for (i = 0; i != stemCount; ++i)
679 stem = [[
stems oo_stringAtIndex:i] lowercaseString];
682 for (j = 0; j != extCount; ++j)
684 extension = [[
extensions oo_stringAtIndex:j] lowercaseString];
685 if (extension !=
nil)
687 [
result addObject:[
stem stringByAppendingString:extension]];
709 return [
NSSet setWithObject:kFileScannerStageName];
715 OOLog(
@"verifyOXP.unusedFiles.unimplemented",
@"%@",
@"TODO: implement unused files check.");
761static BOOL
CheckNameConflict(NSString *lcName, NSDictionary *directoryCases, NSDictionary *rootFiles, NSString **outExisting, NSString **outExistingType)
763 NSString *existing =
nil;
765 existing = [directoryCases objectForKey:lcName];
768 if (outExisting != NULL) *outExisting = existing;
769 if (outExistingType != NULL) *outExistingType =
@"directory";
773 existing = [rootFiles objectForKey:lcName];
776 if (outExisting != NULL) *outExisting = existing;
777 if (outExistingType != NULL) *outExistingType =
@"file";
761static BOOL
CheckNameConflict(NSString *lcName, NSDictionary *directoryCases, NSDictionary *rootFiles, NSString **outExisting, NSString **outExistingType) {
…}
static NSString *const kUnusedListerStageName
static BOOL CheckNameConflict(NSString *lcName, NSDictionary *directoryCases, NSDictionary *rootFiles, NSString **outExisting, NSString **outExistingType)
static NSString *const kFileScannerStageName
#define OOLogOutdentIf(class)
#define OOLog(class, format,...)
#define OOLogIndentIf(class)
NSSet * constructReadMeNames()
OOFileScannerVerifierStage * fileScannerStage()
NSString * nameForDependencyForVerifier:(OOOXPVerifier *verifier)
NSDictionary * scanDirectory:(NSString *path)
id displayNameForFile:andFolder:(NSString *file,[andFolder] NSString *folder)
NSSet * constructReadMeNames()
NSMutableSet * _badPLists
NSMutableSet * _usedFiles
NSString * pathForFile:inFolder:referencedFrom:checkBuiltIn:(NSString *file,[inFolder] NSString *folder,[referencedFrom] NSString *context,[checkBuiltIn] BOOL checkBuiltIn)
NSData * dataForFile:inFolder:referencedFrom:checkBuiltIn:(NSString *file,[inFolder] NSString *folder,[referencedFrom] NSString *context,[checkBuiltIn] BOOL checkBuiltIn)
void checkPListFormat:file:folder:(NSPropertyListFormat format,[file] NSString *file,[folder] NSString *folder)
NSMutableSet * _caseWarnings
NSString * nameForReverseDependencyForVerifier:(OOOXPVerifier *verifier)
OOOXPVerifier * verifier()
id stageWithName:(NSString *name)
NSArray * configurationArrayForKey:(NSString *key)
NSSet * configurationSetForKey:(NSString *key)
void registerStage:(OOOXPVerifierStage *stage)
NSDictionary * configurationDictionaryForKey:(NSString *key)
NSString * pathForFileNamed:inFolder:(NSString *fileName,[inFolder] NSString *folderName)