Oolite
Loading...
Searching...
No Matches
OOOXPVerifier.m
Go to the documentation of this file.
1/*
2
3OOOXPVerifier.m
4
5
6Copyright (C) 2007-2013 Jens Ayton and contributors
7
8Permission is hereby granted, free of charge, to any person obtaining a copy
9of this software and associated documentation files (the "Software"), to deal
10in the Software without restriction, including without limitation the rights
11to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12copies of the Software, and to permit persons to whom the Software is
13furnished to do so, subject to the following conditions:
14
15The above copyright notice and this permission notice shall be included in all
16copies or substantial portions of the Software.
17
18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24SOFTWARE.
25
26*/
27
28/* Design notes:
29 see "verifier design.txt".
30*/
31
32#import "OOOXPVerifier.h"
33
34#if OO_OXP_VERIFIER_ENABLED
35
36#if OOLITE_WINDOWS
37
38#ifdef __OBJC__
39#pragma push_macro("interface")
40#undef interface
41#define interface struct
42#endif
43
44#include <shlwapi.h>
45
46#ifdef __OBJC__
47#pragma pop_macro("interface")
48#endif
49
50#include <tchar.h>
51#endif
52
54#import "OOLoggingExtended.h"
55#import "ResourceManager.h"
57#import "GameController.h"
58#import "OOCacheManager.h"
59#import "OODebugStandards.h"
60
61static void SwitchLogFile(NSString *name);
62static void NoteVerificationStage(NSString *displayName, NSString *stage);
63static void OpenLogFile(NSString *name);
64
65@interface OOOXPVerifier (OOPrivate)
66
67- (id)initWithPath:(NSString *)path;
68- (void)run;
69
70- (void)setUpLogOverrides;
71
72- (void)registerBaseStages;
74- (void)runStages;
75
76- (BOOL)setUpDependencies:(NSSet *)dependencies
77 forStage:(OOOXPVerifierStage *)stage;
78
79- (void)setUpDependents:(NSSet *)dependents
80 forStage:(OOOXPVerifierStage *)stage;
81
82- (void)dumpDebugGraphviz;
83
84@end
85
86
87@implementation OOOXPVerifier
88
96+ (BOOL)runVerificationIfRequested
97{
98 NSArray *arguments = nil;
99 NSEnumerator *argEnum = nil;
100 NSString *arg = nil;
101 NSString *foundPath = nil;
102 BOOL exists, isDirectory;
103 OOOXPVerifier *verifier = nil;
104 NSAutoreleasePool *pool = nil;
105
106 pool = [[NSAutoreleasePool alloc] init];
107
108 arguments = [[NSProcessInfo processInfo] arguments];
109
110 // Scan for -verify-oxp or --verify-oxp followed by relative path
111 for (argEnum = [arguments objectEnumerator]; (arg = [argEnum nextObject]); )
112 {
113 if ([arg isEqual:@"-verify-oxp"] || [arg isEqual:@"--verify-oxp"])
114 {
115 foundPath = [argEnum nextObject];
116 if (foundPath == nil)
117 {
118 OOLog(@"verifyOXP.noPath", @"***** ERROR: %@ passed without path argument; nothing to verify.", arg);
119 [pool release];
120 return YES;
121 }
122 foundPath = [foundPath stringByExpandingTildeInPath];
123 break;
124 }
125 }
126
127 if (foundPath == nil)
128 {
129 [pool release];
130 return NO;
131 }
132
133 // We got a path; does it point to a directory?
134 exists = [[NSFileManager defaultManager] fileExistsAtPath:foundPath isDirectory:&isDirectory];
135 if (!exists)
136 {
137 OOLog(@"verifyOXP.badPath", @"***** ERROR: no OXP exists at path \"%@\"; nothing to verify.", foundPath);
138 }
139 else if (!isDirectory)
140 {
141 OOLog(@"verifyOXP.badPath", @"***** ERROR: \"%@\" is a file, not an OXP directory; nothing to verify.", foundPath);
142 }
143 else
144 {
145 verifier = [[OOOXPVerifier alloc] initWithPath:foundPath];
146 [pool release];
147 pool = [[NSAutoreleasePool alloc] init];
148 [verifier run];
149 [verifier release];
150 }
151 [pool release];
152
153 // Whether or not we got a valid path, -verify-oxp was passed.
154 return YES;
155}
156
157
158- (void)dealloc
159{
160 [_verifierPList release];
161 [_basePath release];
162 [_displayName release];
163 [_stagesByName release];
164 [_waitingStages release];
165
166 [super dealloc];
167}
168
169
170- (void)registerStage:(OOOXPVerifierStage *)stage
171{
172 NSString *name = nil;
173 OOOXPVerifierStage *existing = nil;
174
175 // Sanity checking
176 if (stage == nil) return;
177
178 if (![stage isKindOfClass:[OOOXPVerifierStage class]])
179 {
180 OOLog(@"verifyOXP.registration.failed", @"Attempt to register class %@ as a verifier stage, but it is not a subclass of OOOXPVerifierStage; ignoring.", [stage class]);
181 return;
182 }
183
184 if (!_openForRegistration)
185 {
186 OOLog(@"verifyOXP.registration.failed", @"Attempt to register verifier stage %@ after registration closed, ignoring.", stage);
187 return;
188 }
189
190 name = [stage name];
191 if (name == nil)
192 {
193 OOLog(@"verifyOXP.registration.failed", @"Attempt to register verifier stage %@ with nil name, ignoring.", stage);
194 return;
195 }
196
197 // We can only have one stage with a given name. Registering the same stage twice is OK, though.
198 existing = [_stagesByName objectForKey:name];
199 if (existing == stage) return;
200 if (existing != nil)
201 {
202 OOLog(@"verifyOXP.registration.failed", @"Attempt to register verifier stage %@ with same name as stage %@, ignoring.", stage, existing);
203 return;
204 }
205
206 // Checks passed, store state.
207 [stage setVerifier:self];
208 [_stagesByName setObject:stage forKey:name];
209 [_waitingStages addObject:stage];
210}
211
212
213- (NSString *)oxpPath
214{
215 return [[_basePath retain] autorelease];
216}
217
218
219- (NSString *)oxpDisplayName
220{
221 return [[_displayName retain] autorelease];
222}
223
224
225- (id)stageWithName:(NSString *)name
226{
227 if (name == nil) return nil;
228
229 return [_stagesByName objectForKey:name];
230}
231
232
233- (id)configurationValueForKey:(NSString *)key
234{
235 return [_verifierPList objectForKey:key];
236}
237
238
239- (NSArray *)configurationArrayForKey:(NSString *)key
240{
241 return [_verifierPList oo_arrayForKey:key];
242}
243
244
245- (NSDictionary *)configurationDictionaryForKey:(NSString *)key
246{
247 return [_verifierPList oo_dictionaryForKey:key];
248}
249
250
251- (NSString *)configurationStringForKey:(NSString *)key
252{
253 return [_verifierPList oo_stringForKey:key];
254}
255
256
257- (NSSet *)configurationSetForKey:(NSString *)key
258{
259 NSArray *array = [_verifierPList oo_arrayForKey:key];
260 return array != nil ? [NSSet setWithArray:array] : nil;
261}
262
263@end
264
265
266@implementation OOOXPVerifier (OOPrivate)
267
268- (id)initWithPath:(NSString *)path
269{
270 self = [super init];
271
273
274 NSString *verifierPListPath = [[[ResourceManager builtInPath] stringByAppendingPathComponent:@"Config"] stringByAppendingPathComponent:@"verifyOXP.plist"];
275 _verifierPList = [[NSDictionary dictionaryWithContentsOfFile:verifierPListPath] retain];
276
277 _basePath = [path copy];
278 _displayName = [[NSFileManager defaultManager] displayNameAtPath:_basePath];
279 if (_displayName == nil) _displayName = [_basePath lastPathComponent];
280 [_displayName retain];
281
282 _stagesByName = [[NSMutableDictionary alloc] init];
283 _waitingStages = [[NSMutableSet alloc] init];
284
285 if (_verifierPList == nil ||
286 _basePath == nil)
287 {
288 OOLog(@"verifyOXP.setup.failed", @"%@", @"***** ERROR: failed to set up OXP verifier.");
289 [self release];
290 return nil;
291 }
292
293 _openForRegistration = YES;
294
295 return self;
296}
297
298
299- (void)run
300{
301 NoteVerificationStage(_displayName, @"");
302
303 [self setUpLogOverrides];
304
305 /* We need to be able to look up internal files, but not other OXP files.
306 To do this without clobbering the disk cache, we disable cache writes.
307 */
310 /* FIXME: the OXP verifier should load files from OXPs which have
311 * been explicitly listed as required_oxps in the
312 * manifest. Reading the manifest from the OXP being verified and
313 * setting 'id:<its identifier>' below will do this. */
314 [ResourceManager setUseAddOns:SCENARIO_OXP_DEFINITION_NONE];
315
316 SwitchLogFile(_displayName);
317 OOLog(@"verifyOXP.start", @"Running OXP verifier for %@", _basePath);//_displayName);
318
319 [self registerBaseStages];
320 [self buildDependencyGraph];
321 [self runStages];
322
323 NoteVerificationStage(_displayName, @"");
324 OOLog(@"verifyOXP.done", @"%@", @"OXP verification complete.");
325
326 OpenLogFile(_displayName);
327}
328
329
330- (void)setUpLogOverrides
331{
332 NSDictionary *overrides = nil;
333 NSString *messageClass = nil;
334 id verbose = nil;
335
336 OOLogSetShowMessageClassTemporary([_verifierPList oo_boolForKey:@"logShowMessageClassOverride" defaultValue:NO]);
337
338 overrides = [_verifierPList oo_dictionaryForKey:@"logControlOverride"];
339 foreachkey (messageClass, overrides)
340 {
341 OOLogSetDisplayMessagesInClass(messageClass, [overrides oo_boolForKey:messageClass defaultValue:NO]);
342 }
343
344 /* Since actually editing logControlOverride is a pain, we also allow
345 overriding verifyOXP.verbose through user defaults. This is at least
346 as much a pain under GNUstep, but very convenient under OS X.
347 */
348 verbose = [[NSUserDefaults standardUserDefaults] objectForKey:@"oxp-verifier-verbose-logging"];
349 if (verbose != nil) OOLogSetDisplayMessagesInClass(@"verifyOXP.verbose", OOBooleanFromObject(verbose, NO));
350}
351
352
353- (void)registerBaseStages
354{
355 NSAutoreleasePool *pool = nil;
356 NSSet *stages = nil;
357 NSSet *excludeStages = nil;
358 NSString *stageName = nil;
359 Class stageClass = Nil;
360 OOOXPVerifierStage *stage = nil;
361
362 pool = [[NSAutoreleasePool alloc] init];
363
364 // Load stages specified as array of class names in verifyOXP.plist
365 stages = [self configurationSetForKey:@"stages"];
366 excludeStages = [self configurationSetForKey:@"excludeStages"];
367 if ([excludeStages count] != 0)
368 {
369 stages = [[stages mutableCopy] autorelease];
370 [(NSMutableSet *)stages minusSet:excludeStages];
371 }
372 foreach (stageName, stages)
373 {
374 if ([stageName isKindOfClass:[NSString class]])
375 {
376 stageClass = NSClassFromString(stageName);
377 if (stageClass == Nil)
378 {
379 OOLog(@"verifyOXP.registration.failed", @"Attempt to register unknown class %@ as a verifier stage, ignoring.", stageName);
380 continue;
381 }
382 stage = [[stageClass alloc] init];
383 [self registerStage:stage];
384 [stage release];
385 }
386 }
387
388 [pool release];
389}
390
391
393{
394 NSAutoreleasePool *pool = nil;
395 NSArray *stageKeys = nil;
396 NSString *stageKey = nil;
397 OOOXPVerifierStage *stage = nil;
398 NSString *name = nil;
399 NSMutableDictionary *dependenciesByStage = nil,
400 *dependentsByStage = nil;
401 NSSet *dependencies = nil,
402 *dependents = nil;
403 NSValue *key = nil;
404
405 pool = [[NSAutoreleasePool alloc] init];
406
407 /* Iterate over all stages, getting dependency and dependent sets.
408 This is done in advance so that -dependencies and -dependents may
409 register stages.
410 */
411 dependenciesByStage = [NSMutableDictionary dictionary];
412 dependentsByStage = [NSMutableDictionary dictionary];
413
414 for (;;)
415 {
416 /* Loop while there are stages whose dependency lists haven't been
417 checked. This is an indeterminate loop since new ones can be
418 added.
419 */
420 stage = [_waitingStages anyObject];
421 if (stage == nil) break;
422 [_waitingStages removeObject:stage];
423
424 key = [NSValue valueWithNonretainedObject:stage];
425
426 dependencies = [stage dependencies];
427 if (dependencies != nil)
428 {
429 [dependenciesByStage setObject:dependencies
430 forKey:key];
431 }
432
433 dependents = [stage dependents];
434 if (dependents != nil)
435 {
436 [dependentsByStage setObject:dependents
437 forKey:key];
438 }
439 }
440 [_waitingStages release];
441 _waitingStages = nil;
442 _openForRegistration = NO;
443
444 // Iterate over all stages, resolving dependencies.
445 stageKeys = [_stagesByName allKeys]; // Get the keys up front because we may need to remove entries from dictionary.
446
447 foreach (stageKey, stageKeys)
448 {
449 stage = [_stagesByName objectForKey:stageKey];
450 if (stage == nil) continue;
451
452 // Sanity check
453 name = [stage name];
454 if (![stageKey isEqualToString:name])
455 {
456 OOLog(@"verifyOXP.buildDependencyGraph.badName", @"***** Stage name appears to have changed from \"%@\" to \"%@\" for verifier stage %@, removing.", stageKey, name, stage);
457 [_stagesByName removeObjectForKey:stageKey];
458 continue;
459 }
460
461 // Get dependency set
462 key = [NSValue valueWithNonretainedObject:stage];
463 dependencies = [dependenciesByStage objectForKey:key];
464
465 if (dependencies != nil && ![self setUpDependencies:dependencies forStage:stage])
466 {
467 [_stagesByName removeObjectForKey:stageKey];
468 }
469 }
470
471 /* Iterate over all stages again, resolving reverse dependencies.
472 This is done in a separate pass because reverse dependencies are "weak"
473 while forward dependencies are "strong".
474 */
475 stageKeys = [_stagesByName allKeys];
476
477 foreach (stageKey, stageKeys)
478 {
479 stage = [_stagesByName objectForKey:stageKey];
480 if (stage == nil) continue;
481
482 // Get dependent set
483 key = [NSValue valueWithNonretainedObject:stage];
484 dependents = [dependentsByStage objectForKey:key];
485
486 if (dependents != nil)
487 {
488 [self setUpDependents:dependents forStage:stage];
489 }
490 }
491
492 _waitingStages = [[NSMutableSet alloc] initWithArray:[_stagesByName allValues]];
493 [_waitingStages makeObjectsPerformSelector:@selector(dependencyRegistrationComplete)];
494
495 if ([[NSUserDefaults standardUserDefaults] boolForKey:@"oxp-verifier-dump-debug-graphviz"])
496 {
497 [self dumpDebugGraphviz];
498 }
499
500 [pool release];
501}
502
503
504- (void)runStages
505{
506 NSAutoreleasePool *pool = nil;
507 OOOXPVerifierStage *candidateStage = nil,
508 *stageToRun = nil;
509 NSString *stageName = nil;
510
511 // Loop while there are still stages to run.
512 for (;;)
513 {
514 pool = [[NSAutoreleasePool alloc] init];
515
516 // Look through queue for a stage that's ready
517 stageToRun = nil;
518 foreach (candidateStage, _waitingStages)
519 {
520 if ([candidateStage canRun])
521 {
522 stageToRun = candidateStage;
523 break;
524 }
525 }
526 if (stageToRun == nil)
527 {
528 // No more runnable stages
529 [pool release];
530 break;
531 }
532
533 stageName = nil;
535 @try
536 {
537 stageName = [stageToRun name];
538 if ([stageToRun shouldRun])
539 {
540 NoteVerificationStage(_displayName, stageName);
541 OOLog(@"verifyOXP.runStage", @"%@", stageName);
542 OOLogIndent();
543 [stageToRun performRun];
544 }
545 else
546 {
547 OOLog(@"verifyOXP.verbose.skipStage", @"- Skipping stage: %@ (nothing to do).", stageName);
548 [stageToRun noteSkipped];
549 }
550 }
551 @catch (NSException *exception)
552 {
553 if (stageName == nil) stageName = [[stageToRun class] description];
554 OOLog(@"verifyOXP.exception", @"***** Exception occurred when running OXP verifier stage \"%@\": %@: %@", stageName, [exception name], [exception reason]);
555 }
557
558 [_waitingStages removeObject:stageToRun];
559 [pool release];
560 }
561
562 pool = [[NSAutoreleasePool alloc] init];
563
564 if ([_waitingStages count] != 0)
565 {
566 OOLog(@"verifyOXP.incomplete", @"%@", @"Some verifier stages could not be run:");
567 OOLogIndent();
568 foreach (candidateStage, _waitingStages)
569 {
570 OOLog(@"verifyOXP.incomplete.item", @"%@", candidateStage);
571 }
572 OOLogOutdent();
573 }
574 [_waitingStages release];
575 _waitingStages = nil;
576
577 [pool release];
578}
579
580
581- (BOOL)setUpDependencies:(NSSet *)dependencies
582 forStage:(OOOXPVerifierStage *)stage
583{
584 NSString *depName = nil;
585 OOOXPVerifierStage *depStage = nil;
586
587 // Iterate over dependencies, connecting them up.
588 foreach (depName, dependencies)
589 {
590 depStage = [_stagesByName objectForKey:depName];
591 if (depStage == nil)
592 {
593 OOLog(@"verifyOXP.buildDependencyGraph.unresolved", @"Verifier stage %@ has unresolved dependency \"%@\", skipping.", stage, depName);
594 return NO;
595 }
596
597 if ([depStage isDependentOf:stage])
598 {
599 OOLog(@"verifyOXP.buildDependencyGraph.circularReference", @"Verifier stages %@ and %@ have a dependency loop, skipping.", stage, depStage);
600 [_stagesByName removeObjectForKey:depName];
601 return NO;
602 }
603
604 [stage registerDependency:depStage];
605 }
606
607 return YES;
608}
609
610
611- (void)setUpDependents:(NSSet *)dependents
612 forStage:(OOOXPVerifierStage *)stage
613{
614 NSString *depName = nil;
615 OOOXPVerifierStage *depStage = nil;
616
617 // Iterate over dependents, connecting them up.
618 foreach (depName, dependents)
619 {
620 depStage = [_stagesByName objectForKey:depName];
621 if (depStage == nil)
622 {
623 OOLog(@"verifyOXP.buildDependencyGraph.unresolved", @"Verifier stage %@ has unresolved dependent \"%@\".", stage, depName);
624 continue; // Unresolved/conflicting dependents are non-fatal
625 }
626
627 if ([stage isDependentOf:depStage])
628 {
629 OOLog(@"verifyOXP.buildDependencyGraph.circularReference", @"Verifier stage %@ lists %@ as both dependent and dependency (possibly indirectly); will execute %@ after %@.", stage, depStage, stage, depStage);
630 continue;
631 }
632
633 [depStage registerDependency:stage];
634 }
635}
636
637
638- (void)dumpDebugGraphviz
639{
640 NSMutableString *graphViz = nil;
641 NSDictionary *graphVizTemplate = nil;
642 NSString *template = nil,
643 *startTemplate = nil,
644 *endTemplate = nil;
645 OOOXPVerifierStage *stage = nil;
646 NSSet *deps = nil;
647 OOOXPVerifierStage *dep = nil;
648
649 graphVizTemplate = [self configurationDictionaryForKey:@"debugGraphvizTempate"];
650 graphViz = [NSMutableString stringWithFormat:[graphVizTemplate oo_stringForKey:@"preamble"], [NSDate date]];
651
652 /* Pass 1: enumerate over graph setting node attributes for each stage.
653 We use pointers as node names for simplicity of generation.
654 */
655 template = [graphVizTemplate oo_stringForKey:@"node"];
656 foreach (stage, [_stagesByName allValues])
657 {
658 [graphViz appendFormat:template, stage, [stage class], [stage name]];
659 }
660
661 [graphViz appendString:[graphVizTemplate oo_stringForKey:@"forwardPreamble"]];
662
663 /* Pass 2: enumerate over graph setting forward arcs for each dependency.
664 */
665 template = [graphVizTemplate oo_stringForKey:@"forwardArc"];
666 startTemplate = [graphVizTemplate oo_stringForKey:@"startArc"];
667 foreach (stage, [_stagesByName allValues])
668 {
669 deps = [stage resolvedDependencies];
670 if ([deps count] != 0)
671 {
672 foreach (dep, deps)
673 {
674 [graphViz appendFormat:template, dep, stage];
675 }
676 }
677 else
678 {
679 [graphViz appendFormat:startTemplate, stage];
680 }
681 }
682
683 [graphViz appendString:[graphVizTemplate oo_stringForKey:@"backwardPreamble"]];
684
685 /* Pass 3: enumerate over graph setting backward arcs for each dependent.
686 */
687 template = [graphVizTemplate oo_stringForKey:@"backwardArc"];
688 endTemplate = [graphVizTemplate oo_stringForKey:@"endArc"];
689 foreach (stage, [_stagesByName allValues])
690 {
691 deps = [stage resolvedDependents];
692 if ([deps count] != 0)
693 {
694 foreach (dep, deps)
695 {
696 [graphViz appendFormat:template, dep, stage];
697 }
698 }
699 else
700 {
701 [graphViz appendFormat:endTemplate, stage];
702 }
703 }
704
705 [graphViz appendString:[graphVizTemplate oo_stringForKey:@"postamble"]];
706
707 // Write file
708 [ResourceManager writeDiagnosticString:graphViz toFileNamed:@"OXPVerifierStageDependencies.dot"];
709}
710
711@end
712
713
714#import "OOLogOutputHandler.h"
715
716
717static void SwitchLogFile(NSString *name)
718{
719//#ifndef OOLITE_LINUX
720 name = [name stringByAppendingPathExtension:@"log"];
721 OOLog(@"verifyOXP.switchingLog", @"Switching log files -- logging to \"%@\".", name);
723//#else
724// OOLog(@"verifyOXP.switchingLog", @"Switching logging to <stdout>.");
725// OOLogOutputHandlerStartLoggingToStdout();
726//#endif
727}
728
729
730static void NoteVerificationStage(NSString *displayName, NSString *stage)
731{
732 [[GameController sharedController] logProgress:[NSString stringWithFormat:@"Verifying %@\n%@", displayName, stage]];
733}
734
735
736static void OpenLogFile(NSString *name)
737{
738 // Open log file in appropriate application / provide feedback.
739
740 if ([[NSUserDefaults standardUserDefaults] oo_boolForKey:@"oxp-verifier-open-log" defaultValue:YES])
741 {
742#if OOLITE_MAC_OS_X
743 [[NSWorkspace sharedWorkspace] openFile:OOLogHandlerGetLogPath()];
744#elif OOLITE_WINDOWS
745 // ShellExecute will automatically use the app associated with .log files
746 ShellExecute(NULL, NULL, [OOLogHandlerGetLogPath() UTF8String], NULL, NULL, SW_SHOWNORMAL);
747#elif OOLITE_LINUX
748 // MKW - needed to suppress 'ignoring return value' warning for system() call
749 // int ret;
750 // CIM - and now the compiler complains about that too... casting return
751 // value to void seems to keep it quiet for now
752 // Nothing to do here, since we dump to stdout instead of to a file.
753 //OOLogOutputHandlerStopLoggingToStdout();
754 (void) system([[NSString stringWithFormat:@"cat \"%@\"", OOLogHandlerGetLogPath()] UTF8String]);
755#else
756 do {} while (0);
757#endif
758 }
759}
760
761
762#endif // OO_OXP_VERIFIER_ENABLED
#define foreachkey(VAR, DICT)
Definition OOCocoa.h:353
BOOL OOBooleanFromObject(id object, BOOL defaultValue)
void OOSetStandardsForOXPVerifierMode(void)
NSString * OOLogHandlerGetLogPath(void)
void OOLogOutputHandlerChangeLogFile(NSString *newLogName)
void OOLogPushIndent(void)
Definition OOLogging.m:316
void OOLogPopIndent(void)
Definition OOLogging.m:340
void OOLogOutdent(void)
Definition OOLogging.m:376
#define OOLog(class, format,...)
Definition OOLogging.h:88
void OOLogIndent(void)
Definition OOLogging.m:366
void OOLogSetDisplayMessagesInClass(NSString *inClass, BOOL inFlag)
Definition OOLogging.m:182
void OOLogSetShowMessageClassTemporary(BOOL flag)
Definition OOLogging.m:579
static void SwitchLogFile(NSString *name)
static void NoteVerificationStage(NSString *displayName, NSString *stage)
static void OpenLogFile(NSString *name)
unsigned count
return nil
GameController * sharedController()
void logProgress:(NSString *message)
void setAllowCacheWrites:(BOOL flag)
OOCacheManager * sharedCache()
void setVerifier:(OOOXPVerifier *verifier)
void registerDependency:(OOOXPVerifierStage *dependency)
NSString * builtInPath()
BOOL writeDiagnosticString:toFileNamed:(NSString *string,[toFileNamed] NSString *name)
void setUseAddOns:(NSString *useAddOns)