34#if OO_OXP_VERIFIER_ENABLED
48@interface OOOXPVerifier (OOPrivate)
50- (id)initWithPath:(NSString *)path;
59- (BOOL)setUpDependencies:(NSSet *)dependencies
62- (void)setUpDependents:(NSSet *)dependents
79+ (BOOL)runVerificationIfRequested
81 NSArray *arguments =
nil;
82 NSEnumerator *argEnum =
nil;
84 NSString *foundPath =
nil;
85 BOOL exists, isDirectory;
87 NSAutoreleasePool *pool =
nil;
89 pool = [[NSAutoreleasePool alloc] init];
91 arguments = [[NSProcessInfo processInfo] arguments];
94 for (argEnum = [arguments objectEnumerator]; (arg = [argEnum nextObject]); )
96 if ([arg isEqual:
@"-verify-oxp"] || [arg isEqual:
@"--verify-oxp"])
98 foundPath = [argEnum nextObject];
101 OOLog(
@"verifyOXP.noPath",
@"***** ERROR: %@ passed without path argument; nothing to verify.", arg);
105 foundPath = [foundPath stringByExpandingTildeInPath];
110 if (foundPath ==
nil)
117 exists = [[NSFileManager defaultManager] fileExistsAtPath:foundPath isDirectory:&isDirectory];
120 OOLog(
@"verifyOXP.badPath",
@"***** ERROR: no OXP exists at path \"%@\
"; nothing to verify.", foundPath);
122 else if (!isDirectory)
124 OOLog(
@"verifyOXP.badPath",
@"***** ERROR: \"%@\
" is a file, not an OXP directory; nothing to verify.", foundPath);
130 pool = [[NSAutoreleasePool alloc] init];
143 [_verifierPList release];
145 [_displayName release];
146 [_stagesByName release];
147 [_waitingStages release];
155 NSString *name =
nil;
159 if (stage ==
nil)
return;
163 OOLog(
@"verifyOXP.registration.failed",
@"Attempt to register class %@ as a verifier stage, but it is not a subclass of OOOXPVerifierStage; ignoring.", [stage
class]);
167 if (!_openForRegistration)
169 OOLog(
@"verifyOXP.registration.failed",
@"Attempt to register verifier stage %@ after registration closed, ignoring.", stage);
176 OOLog(
@"verifyOXP.registration.failed",
@"Attempt to register verifier stage %@ with nil name, ignoring.", stage);
181 existing = [_stagesByName objectForKey:name];
182 if (existing == stage)
return;
185 OOLog(
@"verifyOXP.registration.failed",
@"Attempt to register verifier stage %@ with same name as stage %@, ignoring.", stage, existing);
191 [_stagesByName setObject:stage forKey:name];
192 [_waitingStages addObject:stage];
198 return [[_basePath retain] autorelease];
202- (NSString *)oxpDisplayName
204 return [[_displayName retain] autorelease];
208- (id)stageWithName:(NSString *)name
210 if (name ==
nil)
return nil;
212 return [_stagesByName objectForKey:name];
216- (id)configurationValueForKey:(NSString *)key
218 return [_verifierPList objectForKey:key];
222- (NSArray *)configurationArrayForKey:(NSString *)key
224 return [_verifierPList oo_arrayForKey:key];
228- (NSDictionary *)configurationDictionaryForKey:(NSString *)key
230 return [_verifierPList oo_dictionaryForKey:key];
234- (NSString *)configurationStringForKey:(NSString *)key
236 return [_verifierPList oo_stringForKey:key];
240- (NSSet *)configurationSetForKey:(NSString *)key
242 NSArray *array = [_verifierPList oo_arrayForKey:key];
243 return array !=
nil ? [NSSet setWithArray:array] :
nil;
249@implementation OOOXPVerifier (OOPrivate)
251- (id)initWithPath:(NSString *)path
257 NSString *verifierPListPath = [[[
ResourceManager builtInPath] stringByAppendingPathComponent:@"Config"] stringByAppendingPathComponent:@"verifyOXP.plist"];
258 _verifierPList = [[NSDictionary dictionaryWithContentsOfFile:verifierPListPath] retain];
260 _basePath = [path copy];
261 _displayName = [[NSFileManager defaultManager] displayNameAtPath:_basePath];
262 if (_displayName ==
nil) _displayName = [_basePath lastPathComponent];
263 [_displayName retain];
265 _stagesByName = [[NSMutableDictionary alloc] init];
266 _waitingStages = [[NSMutableSet alloc] init];
268 if (_verifierPList ==
nil ||
271 OOLog(
@"verifyOXP.setup.failed",
@"%@",
@"***** ERROR: failed to set up OXP verifier.");
276 _openForRegistration = YES;
286 [
self setUpLogOverrides];
300 OOLog(
@"verifyOXP.start",
@"Running OXP verifier for %@", _basePath);
302 [
self registerBaseStages];
303 [
self buildDependencyGraph];
307 OOLog(
@"verifyOXP.done",
@"%@",
@"OXP verification complete.");
315 NSDictionary *overrides =
nil;
316 NSEnumerator *messageClassEnum =
nil;
317 NSString *messageClass =
nil;
322 overrides = [_verifierPList oo_dictionaryForKey:@"logControlOverride"];
323 for (messageClassEnum = [overrides keyEnumerator]; (messageClass = [messageClassEnum nextObject]); )
332 verbose = [[NSUserDefaults standardUserDefaults] objectForKey:@"oxp-verifier-verbose-logging"];
339 NSAutoreleasePool *pool =
nil;
341 NSSet *excludeStages =
nil;
342 NSEnumerator *stageEnum =
nil;
343 NSString *stageName =
nil;
344 Class stageClass = Nil;
347 pool = [[NSAutoreleasePool alloc] init];
350 stages = [
self configurationSetForKey:@"stages"];
351 excludeStages = [
self configurationSetForKey:@"excludeStages"];
352 if ([excludeStages
count] != 0)
354 stages = [[stages mutableCopy] autorelease];
355 [(NSMutableSet *)stages minusSet:excludeStages];
357 for (stageEnum = [stages objectEnumerator]; (stageName = [stageEnum nextObject]); )
359 if ([stageName isKindOfClass:[NSString
class]])
361 stageClass = NSClassFromString(stageName);
362 if (stageClass == Nil)
364 OOLog(
@"verifyOXP.registration.failed",
@"Attempt to register unknown class %@ as a verifier stage, ignoring.", stageName);
367 stage = [[stageClass alloc] init];
368 [
self registerStage:stage];
379 NSAutoreleasePool *pool =
nil;
380 NSArray *stageKeys =
nil;
381 NSEnumerator *stageEnum =
nil;
382 NSString *stageKey =
nil;
384 NSString *name =
nil;
385 NSMutableDictionary *dependenciesByStage =
nil,
386 *dependentsByStage =
nil;
387 NSSet *dependencies =
nil,
391 pool = [[NSAutoreleasePool alloc] init];
397 dependenciesByStage = [NSMutableDictionary dictionary];
398 dependentsByStage = [NSMutableDictionary dictionary];
406 stage = [_waitingStages anyObject];
407 if (stage ==
nil)
break;
408 [_waitingStages removeObject:stage];
410 key = [NSValue valueWithNonretainedObject:stage];
413 if (dependencies !=
nil)
415 [dependenciesByStage setObject:dependencies
420 if (dependents !=
nil)
422 [dependentsByStage setObject:dependents
426 [_waitingStages release];
427 _waitingStages =
nil;
428 _openForRegistration = NO;
431 stageKeys = [_stagesByName allKeys];
433 for (stageEnum = [stageKeys objectEnumerator]; (stageKey = [stageEnum nextObject]); )
435 stage = [_stagesByName objectForKey:stageKey];
436 if (stage ==
nil)
continue;
440 if (![stageKey isEqualToString:name])
442 OOLog(
@"verifyOXP.buildDependencyGraph.badName",
@"***** Stage name appears to have changed from \"%@\
" to \"%@\" for verifier stage %@, removing.", stageKey, name, stage);
443 [_stagesByName removeObjectForKey:stageKey];
448 key = [NSValue valueWithNonretainedObject:stage];
449 dependencies = [dependenciesByStage objectForKey:key];
451 if (dependencies !=
nil && ![
self setUpDependencies:dependencies forStage:stage])
453 [_stagesByName removeObjectForKey:stageKey];
461 stageKeys = [_stagesByName allKeys];
463 for (stageEnum = [stageKeys objectEnumerator]; (stageKey = [stageEnum nextObject]); )
465 stage = [_stagesByName objectForKey:stageKey];
466 if (stage ==
nil)
continue;
469 key = [NSValue valueWithNonretainedObject:stage];
470 dependents = [dependentsByStage objectForKey:key];
472 if (dependents !=
nil)
474 [
self setUpDependents:dependents forStage:stage];
478 _waitingStages = [[NSMutableSet alloc] initWithArray:[_stagesByName allValues]];
479 [_waitingStages makeObjectsPerformSelector:@selector(dependencyRegistrationComplete)];
481 if ([[NSUserDefaults standardUserDefaults] boolForKey:
@"oxp-verifier-dump-debug-graphviz"])
483 [
self dumpDebugGraphviz];
492 NSAutoreleasePool *pool =
nil;
493 NSEnumerator *stageEnum =
nil;
496 NSString *stageName =
nil;
501 pool = [[NSAutoreleasePool alloc] init];
505 for (stageEnum = [_waitingStages objectEnumerator]; (candidateStage = [stageEnum nextObject]); )
507 if ([candidateStage canRun])
509 stageToRun = candidateStage;
513 if (stageToRun ==
nil)
524 stageName = [stageToRun name];
525 if ([stageToRun shouldRun])
528 OOLog(
@"verifyOXP.runStage",
@"%@", stageName);
530 [stageToRun performRun];
534 OOLog(
@"verifyOXP.verbose.skipStage",
@"- Skipping stage: %@ (nothing to do).", stageName);
535 [stageToRun noteSkipped];
538 @catch (NSException *exception)
540 if (stageName ==
nil) stageName = [[stageToRun class] description];
541 OOLog(
@"verifyOXP.exception",
@"***** Exception occurred when running OXP verifier stage \"%@\
": %@: %@", stageName, [exception name], [exception reason]);
545 [_waitingStages removeObject:stageToRun];
549 pool = [[NSAutoreleasePool alloc] init];
551 if ([_waitingStages
count] != 0)
553 OOLog(
@"verifyOXP.incomplete",
@"%@",
@"Some verifier stages could not be run:");
555 for (stageEnum = [_waitingStages objectEnumerator]; (candidateStage = [stageEnum nextObject]); )
557 OOLog(
@"verifyOXP.incomplete.item",
@"%@", candidateStage);
561 [_waitingStages release];
562 _waitingStages =
nil;
568- (BOOL)setUpDependencies:(NSSet *)dependencies
571 NSString *depName =
nil;
572 NSEnumerator *depEnum =
nil;
576 for (depEnum = [dependencies objectEnumerator]; (depName = [depEnum nextObject]); )
578 depStage = [_stagesByName objectForKey:depName];
581 OOLog(
@"verifyOXP.buildDependencyGraph.unresolved",
@"Verifier stage %@ has unresolved dependency \"%@\
", skipping.", stage, depName);
585 if ([depStage isDependentOf:stage])
587 OOLog(
@"verifyOXP.buildDependencyGraph.circularReference",
@"Verifier stages %@ and %@ have a dependency loop, skipping.", stage, depStage);
588 [_stagesByName removeObjectForKey:depName];
592 [stage registerDependency:depStage];
599- (void)setUpDependents:(NSSet *)dependents
602 NSString *depName =
nil;
603 NSEnumerator *depEnum =
nil;
607 for (depEnum = [dependents objectEnumerator]; (depName = [depEnum nextObject]); )
609 depStage = [_stagesByName objectForKey:depName];
612 OOLog(
@"verifyOXP.buildDependencyGraph.unresolved",
@"Verifier stage %@ has unresolved dependent \"%@\
".", stage, depName);
616 if ([stage isDependentOf:depStage])
618 OOLog(
@"verifyOXP.buildDependencyGraph.circularReference",
@"Verifier stage %@ lists %@ as both dependent and dependency (possibly indirectly); will execute %@ after %@.", stage, depStage, stage, depStage);
622 [depStage registerDependency:stage];
629 NSMutableString *graphViz =
nil;
630 NSDictionary *graphVizTemplate =
nil;
631 NSString *
template =
nil,
632 *startTemplate =
nil,
634 NSEnumerator *stageEnum =
nil;
637 NSEnumerator *depEnum =
nil;
640 graphVizTemplate = [
self configurationDictionaryForKey:@"debugGraphvizTempate"];
641 graphViz = [NSMutableString stringWithFormat:[graphVizTemplate oo_stringForKey:@"preamble"], [NSDate date]];
646 template = [graphVizTemplate oo_stringForKey:@"node"];
647 for (stageEnum = [_stagesByName objectEnumerator]; (stage = [stageEnum nextObject]); )
649 [graphViz appendFormat:template, stage, [stage class], [stage
name]];
652 [graphViz appendString:[graphVizTemplate oo_stringForKey:@"forwardPreamble"]];
656 template = [graphVizTemplate oo_stringForKey:@"forwardArc"];
657 startTemplate = [graphVizTemplate oo_stringForKey:@"startArc"];
658 for (stageEnum = [_stagesByName objectEnumerator]; (stage = [stageEnum nextObject]); )
661 if ([deps
count] != 0)
663 for (depEnum = [deps objectEnumerator]; (dep = [depEnum nextObject]); )
665 [graphViz appendFormat:template, dep, stage];
670 [graphViz appendFormat:startTemplate, stage];
674 [graphViz appendString:[graphVizTemplate oo_stringForKey:@"backwardPreamble"]];
678 template = [graphVizTemplate oo_stringForKey:@"backwardArc"];
679 endTemplate = [graphVizTemplate oo_stringForKey:@"endArc"];
680 for (stageEnum = [_stagesByName objectEnumerator]; (stage = [stageEnum nextObject]); )
683 if ([deps
count] != 0)
685 for (depEnum = [deps objectEnumerator]; (dep = [depEnum nextObject]); )
687 [graphViz appendFormat:template, dep, stage];
692 [graphViz appendFormat:endTemplate, stage];
696 [graphViz appendString:[graphVizTemplate oo_stringForKey:@"postamble"]];
711 name = [name stringByAppendingPathExtension:@"log"];
712 OOLog(
@"verifyOXP.switchingLog",
@"Switching log files -- logging to \"%@\
".", name);
731 if ([[NSUserDefaults standardUserDefaults] oo_boolForKey:
@"oxp-verifier-open-log" defaultValue:YES])
734 [[NSWorkspace sharedWorkspace] openFile:OOLogHandlerGetLogPath()];
737 system([[NSString stringWithFormat:
@"write \"Logs\\%@.log\
"", name] UTF8String]);
void OOSetStandardsForOXPVerifierMode(void)
NSString * OOLogHandlerGetLogPath(void)
void OOLogOutputHandlerChangeLogFile(NSString *newLogName)
void OOLogPushIndent(void)
void OOLogPopIndent(void)
#define OOLog(class, format,...)
void OOLogSetDisplayMessagesInClass(NSString *inClass, BOOL inFlag)
void OOLogSetShowMessageClassTemporary(BOOL flag)
static void SwitchLogFile(NSString *name)
static void NoteVerificationStage(NSString *displayName, NSString *stage)
static void OpenLogFile(NSString *name)
void registerBaseStages()
void buildDependencyGraph()
GameController * sharedController()
void logProgress:(NSString *message)
void setAllowCacheWrites:(BOOL flag)
OOCacheManager * sharedCache()
NSSet * resolvedDependents()
void setVerifier:(OOOXPVerifier *verifier)
NSSet * resolvedDependencies()
BOOL writeDiagnosticString:toFileNamed:(NSString *string,[toFileNamed] NSString *name)
void setUseAddOns:(NSString *useAddOns)