diff --git a/ChangeLog b/ChangeLog index 2762770b5..362118273 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2012-08-10 Richard Frith-Macdonald + + * Source/NSScanner.m: Fix error in comment + * Tools/pldes.m: Update to more modern APIs + * Tools/plser.m: Update to more modern APIs + * Source/NSPropertyList.m: Update for usigned long long + * Source/NSString.m: Make intValue, integerValue, longLongValue + return large unsigned values as negative. + Fixes to try to cope with property lists containing very large + unsigned integers (top bit set). + 2012-08-10 Richard Frith-Macdonald * Source/NSPathUtilities.m: diff --git a/Source/NSPropertyList.m b/Source/NSPropertyList.m index 42c918fb7..e6d2771a4 100644 --- a/Source/NSPropertyList.m +++ b/Source/NSPropertyList.m @@ -316,7 +316,15 @@ foundIgnorableWhitespace: (NSString *)string } else if ([elementName isEqualToString: @"integer"]) { - ASSIGN(plist, [NSNumber numberWithLongLong: [value longLongValue]]); + if ([value hasPrefix: @"-"]) + { + ASSIGN(plist, [NSNumber numberWithLongLong: [value longLongValue]]); + } + else + { + ASSIGN(plist, [NSNumber numberWithUnsignedLongLong: + (unsigned long long)[value longLongValue]]); + } } else if ([elementName isEqualToString: @"real"]) { @@ -1132,7 +1140,21 @@ static id parsePlItem(pldata* pld) for (i = 0; i < len; i++) buf[i] = (char)ptr[i]; buf[len] = '\0'; - result = [[NSNumber alloc] initWithLongLong: atoll(buf)]; + if ('-' == buf[0]) + { + result = [[NSNumber alloc] + initWithLongLong: atoll(buf)]; + } + else + { +#if defined(__MINGW__) + result = [[NSNumber alloc] + initWithUnsignedLongLong: _strtoui64(buf, 0, 10)]; +#else + result = [[NSNumber alloc] + initWithUnsignedLongLong: strtoull(buf, 0, 10)]; +#endif + } } else if (type == 'B') { diff --git a/Source/NSScanner.m b/Source/NSScanner.m index 7c6ffc553..3593a3b11 100644 --- a/Source/NSScanner.m +++ b/Source/NSScanner.m @@ -1220,7 +1220,7 @@ GSScanInt(unichar *buf, unsigned length, int *result) } /** - * Scan in a double value in the standard locale ('.' as decimal poNSInteger).
+ * Scan in a double value in the standard locale ('.' as decimal point).
* Return YES on success, NO on failure.
* The value pointed to by result is unmodified on failure.
* No value is returned in result if it is a null pointer. diff --git a/Source/NSString.m b/Source/NSString.m index d7bc12fd7..804388b8f 100644 --- a/Source/NSString.m +++ b/Source/NSString.m @@ -3332,22 +3332,82 @@ static UCollator *GSICUCollatorOpen(NSStringCompareOptions mask, NSLocale *local /** *

Returns the string's content as an int.
- * Current implementation uses C library atoi(), which does not + * Current implementation uses a C runtime library function, which does not * detect conversion errors -- use with care!

*/ - (int) intValue { - return atoi([self UTF8String]); + const char *ptr = [self UTF8String]; + + while (isspace(*ptr)) + { + ptr++; + } + if ('-' == *ptr) + { + return (int)atoi(ptr); + } + else + { + uint64_t v; + +#if defined(__MINGW__) + v = _strtoui64(ptr, 0, 10); +#else + v = strtoul(ptr, 0, 10); +#endif + return (int)v; + } } - (NSInteger) integerValue { - return atol([self UTF8String]); + const char *ptr = [self UTF8String]; + + while (isspace(*ptr)) + { + ptr++; + } + if ('-' == *ptr) + { + return (NSInteger)atoll(ptr); + } + else + { + uint64_t v; + +#if defined(__MINGW__) + v = _strtoui64(ptr, 0, 10); +#else + v = strtoull(ptr, 0, 10); +#endif + return (NSInteger)v; + } } - (long long) longLongValue { - return atoll([self UTF8String]); + const char *ptr = [self UTF8String]; + + while (isspace(*ptr)) + { + ptr++; + } + if ('-' == *ptr) + { + return atoll(ptr); + } + else + { + unsigned long long l; + +#if defined(__MINGW__) + l = _strtoui64(ptr, 0, 10); +#else + l = strtoull(ptr, 0, 10); +#endif + return (long long)l; + } } // Working With Encodings diff --git a/Tools/pldes.m b/Tools/pldes.m index 34dd916e3..3ad539be0 100644 --- a/Tools/pldes.m +++ b/Tools/pldes.m @@ -27,11 +27,13 @@ #import "Foundation/NSUserDefaults.h" #import "Foundation/NSFileHandle.h" #import "Foundation/NSAutoreleasePool.h" +#import "Foundation/NSPropertyList.h" -/**

This tool converts a binary serialised property list to a text - representation. -

*/ +/**

This tool converts a serialised property list to a text + * representation. + *

+ */ int main(int argc, char** argv, char **env) { @@ -69,15 +71,22 @@ main(int argc, char** argv, char **env) NS_DURING { - NSData *myData; - NSString *myString; - id result; + NSData *myData; + NSString *myString; + id result; + NSPropertyListFormat aFormat; + NSError *anError; myData = [NSData dataWithContentsOfFile: file]; - result = [NSDeserializer deserializePropertyListFromData: myData - mutableContainers: NO]; + result = [NSPropertyListSerialization + propertyListWithData: myData + options: NSPropertyListImmutable + format: &aFormat + error: &anError]; if (result == nil) - GSPrintf(stderr, @"Loading '%@' - nil property list\n", file); + { + GSPrintf(stderr, @"Loading '%@' - %@\n", file, anError); + } else { NSFileHandle *out; diff --git a/Tools/plser.m b/Tools/plser.m index 9d0ff73f9..fcec87ba5 100644 --- a/Tools/plser.m +++ b/Tools/plser.m @@ -27,15 +27,19 @@ #import "Foundation/NSUserDefaults.h" #import "Foundation/NSFileHandle.h" #import "Foundation/NSAutoreleasePool.h" +#import "Foundation/NSPropertyList.h" +#import "Foundation/NSUserDefaults.h" -/**

This tool converts a text property list to a binary serialised - representation. -

*/ +/**

This tool converts a text property list to a another serialised + * representation. + *

+ */ int main(int argc, char** argv, char **env) { NSAutoreleasePool *pool; + NSUserDefaults *defs; NSProcessInfo *proc; NSArray *args; unsigned i; @@ -52,33 +56,106 @@ main(int argc, char** argv, char **env) exit(EXIT_SUCCESS); } + defs = [NSUserDefaults standardUserDefaults]; args = [proc arguments]; - if ([args count] <= 1) + if ([args count] <= 1 + || ([defs objectForKey: @"Format"] != nil && [args count] < 3)) { - GSPrintf(stderr, @"No file names given to serialize.\n"); + GSPrintf(stderr, @"No file names given to serialize. Try --help\n"); } else { + NSString *fmt = [defs stringForKey: @"Format"]; + for (i = 1; i < [args count]; i++) { NSString *file = [args objectAtIndex: i]; + if ([file isEqual: @"--help"]) + { + GSPrintf(stdout, + @"This program takes one or more property list files\n"); + GSPrintf(stdout, + @"as input and reserialises them to stdout.\n"); + GSPrintf(stdout, + @"The only permitted argument is -Format to\n"); + GSPrintf(stdout, + @"specify the output format to use... one of:\n"); + GSPrintf(stdout, + @" NSPropertyListOpenStepFormat\n"); + GSPrintf(stdout, + @" NSPropertyListXMLFormat_v1_0\n"); + GSPrintf(stdout, + @" NSPropertyListBinaryFormat_v1_0\n"); + GSPrintf(stdout, + @" NSPropertyListGNUstepFormat\n"); + GSPrintf(stdout, + @" NSPropertyListGNUstepBinaryFormat\n"); + [pool release]; + exit(EXIT_SUCCESS); + } + if ([file isEqual: @"-Format"]) + { + i++; + continue; + } NS_DURING { - NSData *myData; - NSString *myString; - id result; + NSData *myData; + id incoming; + NSPropertyListFormat inFormat; + NSError *anError; - myString = [NSString stringWithContentsOfFile: file]; - result = [myString propertyList]; - if (result == nil) - GSPrintf(stderr, @"Loading '%@' - nil property list\n", file); + myData = [NSData dataWithContentsOfFile: file]; + incoming = [NSPropertyListSerialization + propertyListWithData: myData + options: NSPropertyListImmutable + format: &inFormat + error: &anError]; + if (nil == incoming) + { + GSPrintf(stderr, @"Loading '%@' - %@\n", file, anError); + } else { - NSFileHandle *out; + NSFileHandle *out; + NSPropertyListFormat outFormat; - myData = [NSSerializer serializePropertyList: result]; + outFormat = NSPropertyListGNUstepBinaryFormat; + if ([fmt isEqual: @"NSPropertyListOpenStepFormat"]) + outFormat = NSPropertyListOpenStepFormat; + else if ([fmt isEqual: @"NSPropertyListXMLFormat_v1_0"]) + outFormat = NSPropertyListXMLFormat_v1_0; + else if ([fmt isEqual: @"NSPropertyListBinaryFormat_v1_0"]) + outFormat = NSPropertyListBinaryFormat_v1_0; + else if ([fmt isEqual: @"NSPropertyListGNUstepFormat"]) + outFormat = NSPropertyListGNUstepFormat; + else if ([fmt isEqual: @"NSPropertyListGNUstepBinaryFormat"]) + outFormat = NSPropertyListGNUstepBinaryFormat; + + myData = [NSPropertyListSerialization + dataWithPropertyList: incoming + format: outFormat + options: 0 + error: &anError]; +#if 0 +/* Check serialisation/deserialisation gives original value. + */ +{ + id result; + result = [NSPropertyListSerialization + propertyListWithData: myData + options: NSPropertyListImmutable + format: 0 + error: &anError]; + + if (NO == [incoming isEqual: result]) + { + NSLog(@"Lossy conversion"); + } +} +#endif out = [NSFileHandle fileHandleWithStandardOutput]; [out writeData: myData]; [out synchronizeFile];