122102af4f
git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@1112 127b21dd-08f5-0310-b4b7-95ae10353056
287 lines
6.5 KiB
Objective-C
287 lines
6.5 KiB
Objective-C
/*
|
|
plistSchemaValidator
|
|
|
|
Test rig for OOPListSchemaVerifier, and also a tool for checking plists
|
|
against schemata.
|
|
|
|
Usage: first argument should be a plist specifying a schema. Subsequent
|
|
arguments are files to test against the schema.
|
|
|
|
Build requirements:
|
|
* Foundation
|
|
* OOPListSchemaVerifier
|
|
* OOLogging
|
|
- OOLogOutputHandler (currently Mac-only)
|
|
- OOAsyncQueue
|
|
* OOCollectionExtractors
|
|
- OOStringParsing.m
|
|
- OOMaths, OOVector, OOQuaternion
|
|
- OOFastArithmetic.m (currently PPC-only)
|
|
* legacy_random.c
|
|
*/
|
|
|
|
#define OO_OXP_VERIFIER_ENABLED 1
|
|
|
|
#import <stdlib.h>
|
|
#import <Foundation/Foundation.h>
|
|
#import "OOPListSchemaVerifier.h"
|
|
#import "OOLogging.h"
|
|
#import "OOMaths.h"
|
|
|
|
|
|
@interface VerifierDelegate: NSObject
|
|
{
|
|
BOOL _notedDelgatedTypes;
|
|
}
|
|
@end
|
|
|
|
|
|
static void RegisterPhonyDefaults(void);
|
|
static OOPListSchemaVerifier *GetVerifier(const char *path);
|
|
static void Verify(OOPListSchemaVerifier *verifier, const char *path);
|
|
static id ReadPList(const char *path);
|
|
|
|
|
|
int main(int argc, const char * argv[])
|
|
{
|
|
NSAutoreleasePool *pool = nil;
|
|
OOPListSchemaVerifier *verifier = nil;
|
|
unsigned i;
|
|
|
|
[[NSAutoreleasePool alloc] init];
|
|
|
|
RegisterPhonyDefaults();
|
|
OOLoggingInit();
|
|
|
|
if (argc < 3)
|
|
{
|
|
OOLog(@"badUsage", @"Usage: %s schema file [, file...]", argc ? argv[0] : "plistschemaverifier");
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
verifier = GetVerifier(argv[1]);
|
|
for (i = 2; i != argc; ++i)
|
|
{
|
|
pool = [[NSAutoreleasePool alloc] init];
|
|
Verify(verifier, argv[i]);
|
|
[pool release];
|
|
}
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
|
|
static void RegisterPhonyDefaults(void)
|
|
{
|
|
NSDictionary *defaults = nil;
|
|
|
|
defaults = [NSMutableDictionary dictionaryWithObjectsAndKeys:
|
|
[NSNumber numberWithBool:NO], @"logging-show-class",
|
|
[NSNumber numberWithBool:YES], @"logging-echo-to-stderr",
|
|
nil];
|
|
|
|
[[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
|
|
}
|
|
|
|
|
|
static OOPListSchemaVerifier *GetVerifier(const char *path)
|
|
{
|
|
id schema = nil;
|
|
OOPListSchemaVerifier *verifier = nil;
|
|
VerifierDelegate *delegate = nil;
|
|
|
|
schema = ReadPList(path);
|
|
if (schema == nil)
|
|
{
|
|
OOLog(@"badSchema", @"Could not read schema.");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
verifier = [OOPListSchemaVerifier verifierWithSchema:schema];
|
|
if (verifier == nil)
|
|
{
|
|
OOLog(@"badSchema", @"Could not interpret %s as a schema.", path);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
delegate = [[VerifierDelegate alloc] init];
|
|
[verifier setDelegate:delegate];
|
|
|
|
return verifier;
|
|
}
|
|
|
|
|
|
static void Verify(OOPListSchemaVerifier *verifier, const char *path)
|
|
{
|
|
id plist = nil;
|
|
NSString *name = nil;
|
|
|
|
plist = ReadPList(path);
|
|
if (plist != nil)
|
|
{
|
|
name = [NSString stringWithUTF8String:path];
|
|
if (name == nil) name = [NSString stringWithCString:path];
|
|
name = [name lastPathComponent];
|
|
|
|
OOLog(@"verifying", @"Verifying %@:", name);
|
|
OOLogIndent();
|
|
if ([verifier verifyPropertyList:plist named:name])
|
|
{
|
|
OOLog(@"verifying.success", @"OK.");
|
|
}
|
|
OOLogOutdent();
|
|
}
|
|
}
|
|
|
|
|
|
static id ReadPList(const char *path)
|
|
{
|
|
NSString *nsPath = nil;
|
|
NSData *data = nil;
|
|
id result = nil;
|
|
NSString *error = nil;
|
|
|
|
nsPath = [NSString stringWithUTF8String:path];
|
|
if (nsPath == nil) nsPath = [NSString stringWithCString:path];
|
|
|
|
if (nsPath == nil)
|
|
{
|
|
OOLog(@"badPath", @"Could not interpret \"%s\" as a path.", path);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
data = [[NSData alloc] initWithContentsOfFile:nsPath];
|
|
if (data == nil)
|
|
{
|
|
OOLog(@"readError", @"Could not read %@.", nsPath);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
result = [NSPropertyListSerialization propertyListFromData:data
|
|
mutabilityOption:NSPropertyListImmutable
|
|
format:NULL
|
|
errorDescription:&error];
|
|
[data release];
|
|
if (result == nil)
|
|
{
|
|
OOLog(@"badPList", @"Could not interpret contents of %@ as a property list: %@.", nsPath, error);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
@implementation VerifierDelegate
|
|
|
|
- (BOOL)verifier:(OOPListSchemaVerifier *)verifier
|
|
withPropertyList:(id)rootPList
|
|
named:(NSString *)name
|
|
testProperty:(id)subPList
|
|
atPath:(NSArray *)keyPath
|
|
againstType:(NSString *)typeKey
|
|
error:(NSError **)outError
|
|
{
|
|
if (!_notedDelgatedTypes)
|
|
{
|
|
OOLog(@"delegatedTypes", @"Plist schema uses delegated types; all delegated types will be treated as matching.");
|
|
_notedDelgatedTypes = YES;
|
|
}
|
|
|
|
return YES;
|
|
}
|
|
|
|
@end
|
|
|
|
|
|
/****** Shims *******
|
|
Everything beyond this point is stuff that's needed to link, but whose full
|
|
behaviour is not needed.
|
|
*/
|
|
|
|
@interface ResourceManager: NSObject
|
|
+ (NSArray *)rootPaths;
|
|
@end
|
|
|
|
|
|
@implementation ResourceManager
|
|
+ (NSArray *)rootPaths
|
|
{
|
|
return [NSArray array];
|
|
}
|
|
@end
|
|
|
|
|
|
NSDictionary *OODictionaryFromFile(NSString *path)
|
|
{
|
|
return [NSDictionary dictionaryWithContentsOfFile:path];
|
|
}
|
|
|
|
static NSString * const kOOLogStringVectorConversion = @"strings.conversion.vector";
|
|
static NSString * const kOOLogStringQuaternionConversion = @"strings.conversion.quaternion";
|
|
|
|
BOOL ScanVectorFromString(NSString *xyzString, Vector *outVector)
|
|
{
|
|
GLfloat xyz[] = {0.0, 0.0, 0.0};
|
|
int i = 0;
|
|
NSString *error = nil;
|
|
NSScanner *scanner = nil;
|
|
|
|
if (xyzString == nil) return NO;
|
|
else if (outVector == NULL) error = @"nil result pointer";
|
|
|
|
if (!error) scanner = [NSScanner scannerWithString:xyzString];
|
|
while (![scanner isAtEnd] && i < 3 && !error)
|
|
{
|
|
if (![scanner scanFloat:&xyz[i++]]) error = @"could not scan a float value.";
|
|
}
|
|
|
|
if (!error && i < 3) error = @"found less than three float values.";
|
|
|
|
if (!error)
|
|
{
|
|
*outVector = make_vector(xyz[0], xyz[1], xyz[2]);
|
|
return YES;
|
|
}
|
|
else
|
|
{
|
|
OOLog(kOOLogStringVectorConversion, @"***** ERROR cannot make vector from '%@': %@", xyzString, error);
|
|
return NO;
|
|
}
|
|
}
|
|
|
|
|
|
BOOL ScanQuaternionFromString(NSString *wxyzString, Quaternion *outQuaternion)
|
|
{
|
|
GLfloat wxyz[] = {1.0, 0.0, 0.0, 0.0};
|
|
int i = 0;
|
|
NSString *error = nil;
|
|
NSScanner *scanner = nil;
|
|
|
|
if (wxyzString == nil) return NO;
|
|
else if (outQuaternion == NULL) error = @"nil result pointer";
|
|
|
|
if (!error) scanner = [NSScanner scannerWithString:wxyzString];
|
|
while (![scanner isAtEnd] && i < 4 && !error)
|
|
{
|
|
if (![scanner scanFloat:&wxyz[i++]]) error = @"could not scan a float value.";
|
|
}
|
|
|
|
if (!error && i < 4) error = @"found less than four float values.";
|
|
|
|
if (!error)
|
|
{
|
|
outQuaternion->w = wxyz[0];
|
|
outQuaternion->x = wxyz[1];
|
|
outQuaternion->y = wxyz[2];
|
|
outQuaternion->z = wxyz[3];
|
|
quaternion_normalize(outQuaternion);
|
|
return YES;
|
|
}
|
|
else
|
|
{
|
|
OOLog(kOOLogStringQuaternionConversion, @"***** ERROR cannot make quaternion from '%@': %@", wxyzString, error);
|
|
return NO;
|
|
}
|
|
}
|
|
|