Oolite 1.91.0.7745-260117-205bce7
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
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
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];
321 [self runStages];
322
323 NoteVerificationStage(_displayName, @"");
324 OOLog(@"verifyOXP.done", @"%@", @"OXP verification complete.");
325
326 OpenLogFile(_displayName);
327}
328
329
331{
332 NSDictionary *overrides = nil;
333 NSEnumerator *messageClassEnum = nil;
334 NSString *messageClass = nil;
335 id verbose = nil;
336
337 OOLogSetShowMessageClassTemporary([_verifierPList oo_boolForKey:@"logShowMessageClassOverride" defaultValue:NO]);
338
339 overrides = [_verifierPList oo_dictionaryForKey:@"logControlOverride"];
340 for (messageClassEnum = [overrides keyEnumerator]; (messageClass = [messageClassEnum nextObject]); )
341 {
342 OOLogSetDisplayMessagesInClass(messageClass, [overrides oo_boolForKey:messageClass defaultValue:NO]);
343 }
344
345 /* Since actually editing logControlOverride is a pain, we also allow
346 overriding verifyOXP.verbose through user defaults. This is at least
347 as much a pain under GNUstep, but very convenient under OS X.
348 */
349 verbose = [[NSUserDefaults standardUserDefaults] objectForKey:@"oxp-verifier-verbose-logging"];
350 if (verbose != nil) OOLogSetDisplayMessagesInClass(@"verifyOXP.verbose", OOBooleanFromObject(verbose, NO));
351}
352
353
355{
356 NSAutoreleasePool *pool = nil;
357 NSSet *stages = nil;
358 NSSet *excludeStages = nil;
359 NSEnumerator *stageEnum = nil;
360 NSString *stageName = nil;
361 Class stageClass = Nil;
362 OOOXPVerifierStage *stage = nil;
363
364 pool = [[NSAutoreleasePool alloc] init];
365
366 // Load stages specified as array of class names in verifyOXP.plist
367 stages = [self configurationSetForKey:@"stages"];
368 excludeStages = [self configurationSetForKey:@"excludeStages"];
369 if ([excludeStages count] != 0)
370 {
371 stages = [[stages mutableCopy] autorelease];
372 [(NSMutableSet *)stages minusSet:excludeStages];
373 }
374 for (stageEnum = [stages objectEnumerator]; (stageName = [stageEnum nextObject]); )
375 {
376 if ([stageName isKindOfClass:[NSString class]])
377 {
378 stageClass = NSClassFromString(stageName);
379 if (stageClass == Nil)
380 {
381 OOLog(@"verifyOXP.registration.failed", @"Attempt to register unknown class %@ as a verifier stage, ignoring.", stageName);
382 continue;
383 }
384 stage = [[stageClass alloc] init];
385 [self registerStage:stage];
386 [stage release];
387 }
388 }
389
390 [pool release];
391}
392
393
395{
396 NSAutoreleasePool *pool = nil;
397 NSArray *stageKeys = nil;
398 NSEnumerator *stageEnum = nil;
399 NSString *stageKey = nil;
400 OOOXPVerifierStage *stage = nil;
401 NSString *name = nil;
402 NSMutableDictionary *dependenciesByStage = nil,
403 *dependentsByStage = nil;
404 NSSet *dependencies = nil,
405 *dependents = nil;
406 NSValue *key = nil;
407
408 pool = [[NSAutoreleasePool alloc] init];
409
410 /* Iterate over all stages, getting dependency and dependent sets.
411 This is done in advance so that -dependencies and -dependents may
412 register stages.
413 */
414 dependenciesByStage = [NSMutableDictionary dictionary];
415 dependentsByStage = [NSMutableDictionary dictionary];
416
417 for (;;)
418 {
419 /* Loop while there are stages whose dependency lists haven't been
420 checked. This is an indeterminate loop since new ones can be
421 added.
422 */
423 stage = [_waitingStages anyObject];
424 if (stage == nil) break;
425 [_waitingStages removeObject:stage];
426
427 key = [NSValue valueWithNonretainedObject:stage];
428
429 dependencies = [stage dependencies];
430 if (dependencies != nil)
431 {
432 [dependenciesByStage setObject:dependencies
433 forKey:key];
434 }
435
436 dependents = [stage dependents];
437 if (dependents != nil)
438 {
439 [dependentsByStage setObject:dependents
440 forKey:key];
441 }
442 }
443 [_waitingStages release];
444 _waitingStages = nil;
445 _openForRegistration = NO;
446
447 // Iterate over all stages, resolving dependencies.
448 stageKeys = [_stagesByName allKeys]; // Get the keys up front because we may need to remove entries from dictionary.
449
450 for (stageEnum = [stageKeys objectEnumerator]; (stageKey = [stageEnum nextObject]); )
451 {
452 stage = [_stagesByName objectForKey:stageKey];
453 if (stage == nil) continue;
454
455 // Sanity check
456 name = [stage name];
457 if (![stageKey isEqualToString:name])
458 {
459 OOLog(@"verifyOXP.buildDependencyGraph.badName", @"***** Stage name appears to have changed from \"%@\" to \"%@\" for verifier stage %@, removing.", stageKey, name, stage);
460 [_stagesByName removeObjectForKey:stageKey];
461 continue;
462 }
463
464 // Get dependency set
465 key = [NSValue valueWithNonretainedObject:stage];
466 dependencies = [dependenciesByStage objectForKey:key];
467
468 if (dependencies != nil && ![self setUpDependencies:dependencies forStage:stage])
469 {
470 [_stagesByName removeObjectForKey:stageKey];
471 }
472 }
473
474 /* Iterate over all stages again, resolving reverse dependencies.
475 This is done in a separate pass because reverse dependencies are "weak"
476 while forward dependencies are "strong".
477 */
478 stageKeys = [_stagesByName allKeys];
479
480 for (stageEnum = [stageKeys objectEnumerator]; (stageKey = [stageEnum nextObject]); )
481 {
482 stage = [_stagesByName objectForKey:stageKey];
483 if (stage == nil) continue;
484
485 // Get dependent set
486 key = [NSValue valueWithNonretainedObject:stage];
487 dependents = [dependentsByStage objectForKey:key];
488
489 if (dependents != nil)
490 {
491 [self setUpDependents:dependents forStage:stage];
492 }
493 }
494
495 _waitingStages = [[NSMutableSet alloc] initWithArray:[_stagesByName allValues]];
496 [_waitingStages makeObjectsPerformSelector:@selector(dependencyRegistrationComplete)];
497
498 if ([[NSUserDefaults standardUserDefaults] boolForKey:@"oxp-verifier-dump-debug-graphviz"])
499 {
500 [self dumpDebugGraphviz];
501 }
502
503 [pool release];
504}
505
506
508{
509 NSAutoreleasePool *pool = nil;
510 NSEnumerator *stageEnum = nil;
511 OOOXPVerifierStage *candidateStage = nil,
512 *stageToRun = nil;
513 NSString *stageName = nil;
514
515 // Loop while there are still stages to run.
516 for (;;)
517 {
518 pool = [[NSAutoreleasePool alloc] init];
519
520 // Look through queue for a stage that's ready
521 stageToRun = nil;
522 for (stageEnum = [_waitingStages objectEnumerator]; (candidateStage = [stageEnum nextObject]); )
523 {
524 if ([candidateStage canRun])
525 {
526 stageToRun = candidateStage;
527 break;
528 }
529 }
530 if (stageToRun == nil)
531 {
532 // No more runnable stages
533 [pool release];
534 break;
535 }
536
537 stageName = nil;
539 @try
540 {
541 stageName = [stageToRun name];
542 if ([stageToRun shouldRun])
543 {
544 NoteVerificationStage(_displayName, stageName);
545 OOLog(@"verifyOXP.runStage", @"%@", stageName);
546 OOLogIndent();
547 [stageToRun performRun];
548 }
549 else
550 {
551 OOLog(@"verifyOXP.verbose.skipStage", @"- Skipping stage: %@ (nothing to do).", stageName);
552 [stageToRun noteSkipped];
553 }
554 }
555 @catch (NSException *exception)
556 {
557 if (stageName == nil) stageName = [[stageToRun class] description];
558 OOLog(@"verifyOXP.exception", @"***** Exception occurred when running OXP verifier stage \"%@\": %@: %@", stageName, [exception name], [exception reason]);
559 }
561
562 [_waitingStages removeObject:stageToRun];
563 [pool release];
564 }
565
566 pool = [[NSAutoreleasePool alloc] init];
567
568 if ([_waitingStages count] != 0)
569 {
570 OOLog(@"verifyOXP.incomplete", @"%@", @"Some verifier stages could not be run:");
571 OOLogIndent();
572 for (stageEnum = [_waitingStages objectEnumerator]; (candidateStage = [stageEnum nextObject]); )
573 {
574 OOLog(@"verifyOXP.incomplete.item", @"%@", candidateStage);
575 }
576 OOLogOutdent();
577 }
578 [_waitingStages release];
579 _waitingStages = nil;
580
581 [pool release];
582}
583
584
585- (BOOL)setUpDependencies:(NSSet *)dependencies
586 forStage:(OOOXPVerifierStage *)stage
587{
588 NSString *depName = nil;
589 NSEnumerator *depEnum = nil;
590 OOOXPVerifierStage *depStage = nil;
591
592 // Iterate over dependencies, connecting them up.
593 for (depEnum = [dependencies objectEnumerator]; (depName = [depEnum nextObject]); )
594 {
595 depStage = [_stagesByName objectForKey:depName];
596 if (depStage == nil)
597 {
598 OOLog(@"verifyOXP.buildDependencyGraph.unresolved", @"Verifier stage %@ has unresolved dependency \"%@\", skipping.", stage, depName);
599 return NO;
600 }
601
602 if ([depStage isDependentOf:stage])
603 {
604 OOLog(@"verifyOXP.buildDependencyGraph.circularReference", @"Verifier stages %@ and %@ have a dependency loop, skipping.", stage, depStage);
605 [_stagesByName removeObjectForKey:depName];
606 return NO;
607 }
608
609 [stage registerDependency:depStage];
610 }
611
612 return YES;
613}
614
615
616- (void)setUpDependents:(NSSet *)dependents
617 forStage:(OOOXPVerifierStage *)stage
618{
619 NSString *depName = nil;
620 NSEnumerator *depEnum = nil;
621 OOOXPVerifierStage *depStage = nil;
622
623 // Iterate over dependents, connecting them up.
624 for (depEnum = [dependents objectEnumerator]; (depName = [depEnum nextObject]); )
625 {
626 depStage = [_stagesByName objectForKey:depName];
627 if (depStage == nil)
628 {
629 OOLog(@"verifyOXP.buildDependencyGraph.unresolved", @"Verifier stage %@ has unresolved dependent \"%@\".", stage, depName);
630 continue; // Unresolved/conflicting dependents are non-fatal
631 }
632
633 if ([stage isDependentOf:depStage])
634 {
635 OOLog(@"verifyOXP.buildDependencyGraph.circularReference", @"Verifier stage %@ lists %@ as both dependent and dependency (possibly indirectly); will execute %@ after %@.", stage, depStage, stage, depStage);
636 continue;
637 }
638
639 [depStage registerDependency:stage];
640 }
641}
642
643
645{
646 NSMutableString *graphViz = nil;
647 NSDictionary *graphVizTemplate = nil;
648 NSString *template = nil,
649 *startTemplate = nil,
650 *endTemplate = nil;
651 NSEnumerator *stageEnum = nil;
652 OOOXPVerifierStage *stage = nil;
653 NSSet *deps = nil;
654 NSEnumerator *depEnum = nil;
655 OOOXPVerifierStage *dep = nil;
656
657 graphVizTemplate = [self configurationDictionaryForKey:@"debugGraphvizTempate"];
658 graphViz = [NSMutableString stringWithFormat:[graphVizTemplate oo_stringForKey:@"preamble"], [NSDate date]];
659
660 /* Pass 1: enumerate over graph setting node attributes for each stage.
661 We use pointers as node names for simplicity of generation.
662 */
663 template = [graphVizTemplate oo_stringForKey:@"node"];
664 for (stageEnum = [_stagesByName objectEnumerator]; (stage = [stageEnum nextObject]); )
665 {
666 [graphViz appendFormat:template, stage, [stage class], [stage name]];
667 }
668
669 [graphViz appendString:[graphVizTemplate oo_stringForKey:@"forwardPreamble"]];
670
671 /* Pass 2: enumerate over graph setting forward arcs for each dependency.
672 */
673 template = [graphVizTemplate oo_stringForKey:@"forwardArc"];
674 startTemplate = [graphVizTemplate oo_stringForKey:@"startArc"];
675 for (stageEnum = [_stagesByName objectEnumerator]; (stage = [stageEnum nextObject]); )
676 {
678 if ([deps count] != 0)
679 {
680 for (depEnum = [deps objectEnumerator]; (dep = [depEnum nextObject]); )
681 {
682 [graphViz appendFormat:template, dep, stage];
683 }
684 }
685 else
686 {
687 [graphViz appendFormat:startTemplate, stage];
688 }
689 }
690
691 [graphViz appendString:[graphVizTemplate oo_stringForKey:@"backwardPreamble"]];
692
693 /* Pass 3: enumerate over graph setting backward arcs for each dependent.
694 */
695 template = [graphVizTemplate oo_stringForKey:@"backwardArc"];
696 endTemplate = [graphVizTemplate oo_stringForKey:@"endArc"];
697 for (stageEnum = [_stagesByName objectEnumerator]; (stage = [stageEnum nextObject]); )
698 {
699 deps = [stage resolvedDependents];
700 if ([deps count] != 0)
701 {
702 for (depEnum = [deps objectEnumerator]; (dep = [depEnum nextObject]); )
703 {
704 [graphViz appendFormat:template, dep, stage];
705 }
706 }
707 else
708 {
709 [graphViz appendFormat:endTemplate, stage];
710 }
711 }
712
713 [graphViz appendString:[graphVizTemplate oo_stringForKey:@"postamble"]];
714
715 // Write file
716 [ResourceManager writeDiagnosticString:graphViz toFileNamed:@"OXPVerifierStageDependencies.dot"];
717}
718
719@end
720
721
722#import "OOLogOutputHandler.h"
723
724
725static void SwitchLogFile(NSString *name)
726{
727//#ifndef OOLITE_LINUX
728 name = [name stringByAppendingPathExtension:@"log"];
729 OOLog(@"verifyOXP.switchingLog", @"Switching log files -- logging to \"%@\".", name);
731//#else
732// OOLog(@"verifyOXP.switchingLog", @"Switching logging to <stdout>.");
733// OOLogOutputHandlerStartLoggingToStdout();
734//#endif
735}
736
737
738static void NoteVerificationStage(NSString *displayName, NSString *stage)
739{
740 [[GameController sharedController] logProgress:[NSString stringWithFormat:@"Verifying %@\n%@", displayName, stage]];
741}
742
743
744static void OpenLogFile(NSString *name)
745{
746 // Open log file in appropriate application / provide feedback.
747
748 if ([[NSUserDefaults standardUserDefaults] oo_boolForKey:@"oxp-verifier-open-log" defaultValue:YES])
749 {
750#if OOLITE_MAC_OS_X
751 [[NSWorkspace sharedWorkspace] openFile:OOLogHandlerGetLogPath()];
752#elif OOLITE_WINDOWS
753 // ShellExecute will automatically use the app associated with .log files
754 ShellExecute(NULL, NULL, [OOLogHandlerGetLogPath() UTF8String], NULL, NULL, SW_SHOWNORMAL);
755#elif OOLITE_LINUX
756 // MKW - needed to suppress 'ignoring return value' warning for system() call
757 // int ret;
758 // CIM - and now the compiler complains about that too... casting return
759 // value to void seems to keep it quiet for now
760 // Nothing to do here, since we dump to stdout instead of to a file.
761 //OOLogOutputHandlerStopLoggingToStdout();
762 (void) system([[NSString stringWithFormat:@"cat \"%@\"", OOLogHandlerGetLogPath()] UTF8String]);
763#else
764 do {} while (0);
765#endif
766 }
767}
768
769
770#endif // OO_OXP_VERIFIER_ENABLED
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
BOOL runVerificationIfRequested()
GameController * sharedController()
void logProgress:(NSString *message)
void setAllowCacheWrites:(BOOL flag)
OOCacheManager * sharedCache()
void setVerifier:(OOOXPVerifier *verifier)
void registerBaseStages()
void setUpDependents:forStage:(NSSet *dependents,[forStage] OOOXPVerifierStage *stage)
BOOL _openForRegistration
NSSet * configurationSetForKey:(NSString *key)
void buildDependencyGraph()
void registerStage:(OOOXPVerifierStage *stage)
NSDictionary * configurationDictionaryForKey:(NSString *key)
NSString * oxpPath()
NSString * oxpDisplayName()
NSString * builtInPath()
BOOL writeDiagnosticString:toFileNamed:(NSString *string,[toFileNamed] NSString *name)
void setUseAddOns:(NSString *useAddOns)