From 5f4545a79a942caa4999a7f99663e2848db4d878 Mon Sep 17 00:00:00 2001 From: Adam Fedor Date: Thu, 18 Sep 1997 14:56:47 +0000 Subject: [PATCH] Improved -description writing/reading. Bug fixes to NSString. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@2429 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 24 +++++++++++++++++ Headers/gnustep/base/NSValue.h | 4 +++ Source/Dictionary.m | 48 +++++++++++++++++++++++++++------- Source/NSArray.m | 3 +-- Source/NSCTemplateValue.m | 10 +++---- Source/NSCharacterSet.m | 9 ++++--- Source/NSDictionary.m | 22 +++------------- Source/NSNumber.m | 16 ++++++++++++ Source/NSString.m | 12 +++++---- Source/NSValue.m | 35 +++++++++++++++++++++++++ 10 files changed, 139 insertions(+), 44 deletions(-) diff --git a/ChangeLog b/ChangeLog index 084ac4f89..5e0eb5ea7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +Tue Sep 16 15:50:39 1997 Adam Fedor + + * src/Dictionary.m ([Dictionary -descriptionWithIndent:]): Rewrite + to pretty-print description. + * src/NSDictionary.m ([NSDictionary -description]): Remove + redundant method implementation. + ([NSDictionary -descriptionWithIndent:]): Likewise. + * src/NSArray.m ([NSArray -descriptionWithIndent:]): Implement. + + * src/NSCTemplateValue ([NSCTemplateValue description]): Add + semicolon to last value. + * src/NSValue: ([NSValue valueFromString:]): New method. + * src/NSNumber: ([NSValue valueFromString:]): Likewise. + * src/include/NSValue.h: Define new method. + + * src/NSCharacterSet.m ([NSCharacterSet -_bitmapForSet:]): Fix + test path name. + + * src/NSString ([NSString initWithFormat:arguments:]): Take care + of formatted string case "%*s". + ([NSString -stringByAppendingPathComponent:]): Exception only if + string starts with '/'. + ([NSString -stringByAppendingPathExtension:]): Likewise. + Mon Sep 15 21:27:00 1997 Richard Frith-Macdonald * src/NSHData.m: Fixed a couple of bugs occurring when allocation of diff --git a/Headers/gnustep/base/NSValue.h b/Headers/gnustep/base/NSValue.h index 2de7e1e97..31ccc9fac 100644 --- a/Headers/gnustep/base/NSValue.h +++ b/Headers/gnustep/base/NSValue.h @@ -40,6 +40,10 @@ + (NSValue*) valueWithRect: (NSRect)rect; + (NSValue*) valueWithSize: (NSSize)size; +#ifndef STRICT_OPENSTEP ++ valueFromString: (NSString *)string; +#endif + // Accessing Data - (void) getValue: (void*)value; diff --git a/Source/Dictionary.m b/Source/Dictionary.m index 59f77d030..9fc855b51 100644 --- a/Source/Dictionary.m +++ b/Source/Dictionary.m @@ -23,6 +23,7 @@ #include #include +#include #define DEFAULT_DICTIONARY_CAPACITY 32 @@ -204,30 +205,57 @@ OBJC_FREE (*enumState); } -- (NSString*) description +- (NSString*) descriptionWithIndent: (unsigned)level { + int dict_count; id desc; id keyenum = [self keyEnumerator]; id key; + NSCharacterSet *quotables; + quotables = [[NSCharacterSet alphanumericCharacterSet] invertedSet]; + + dict_count = [self count]; desc = [NSMutableString stringWithCapacity: 2]; [desc appendString: @"{"]; + if (dict_count > 0) + [desc appendString: @"\n"]; while ((key = [keyenum nextObject])) { - /* I wish appendString: returned self*/ - [desc appendString: [key description]]; - [desc appendString: @" = "]; - [desc appendString: [[self objectAtKey: key] description]]; - [desc appendString: @"; "]; + NSString *string; + id object; + string = [key description]; + if ([string rangeOfCharacterFromSet: quotables].length > 0) + [desc appendFormat: @"%*s \"%@\" = ", level, "", string]; + else + [desc appendFormat: @"%*s %@ = ", level, "", string]; + object = [self objectAtKey: key]; + if ([object respondsToSelector: @selector(descriptionWithIndent:)]) + { + /* This a dictionary or array, so don't quote it */ + string = [object descriptionWithIndent: level+2]; + [desc appendFormat: @"%@;\n", string]; + } + else + { + /* This should be a string or number, so decide if we need to + quote it */ + string = [object description]; + if ([string rangeOfCharacterFromSet: quotables].length > 0) + [desc appendFormat: @"\"%@\";\n", string]; + else + [desc appendFormat: @"%@;\n", string]; + } } - [desc appendString: @"}"]; + if (dict_count == 0) + level = 0; + [desc appendFormat: @"%*s}", level, ""]; return desc; } -- (NSString*) descriptionWithIndent: (unsigned)level +- (NSString*) description { - return [NSString stringWithFormat:@"%*s%s", - level, "", [[self description] cStringNoCopy]]; + return [self descriptionWithIndent: 0]; } @end diff --git a/Source/NSArray.m b/Source/NSArray.m index ad3a49d6d..6bc2f0775 100644 --- a/Source/NSArray.m +++ b/Source/NSArray.m @@ -407,8 +407,7 @@ static Class NSMutableArray_concrete_class; - (NSString*) descriptionWithIndent: (unsigned)level { - [self notImplemented:_cmd]; - return nil; + return [self description]; } /* The NSCopying Protocol */ diff --git a/Source/NSCTemplateValue.m b/Source/NSCTemplateValue.m index e5e2d1c10..8e942f154 100644 --- a/Source/NSCTemplateValue.m +++ b/Source/NSCTemplateValue.m @@ -90,17 +90,17 @@ - (NSString *) description { #if TYPE_ORDER == 0 - return [NSString stringWithFormat: @"{object = %@}", [data description]]; + return [NSString stringWithFormat: @"{object = %@;}", [data description]]; #elif TYPE_ORDER == 1 - return [NSString stringWithFormat: @"{x = %g; y = %g}", data.x, data.y]; + return [NSString stringWithFormat: @"{x = %g; y = %g;}", data.x, data.y]; #elif TYPE_ORDER == 2 - return [NSString stringWithFormat: @"{pointer = %p}", data]; + return [NSString stringWithFormat: @"{pointer = %p;}", data]; #elif TYPE_ORDER == 3 return [NSString stringWithFormat: - @"{x = %g; y = %g; width = %g; height = %g}", NSMinX(data), NSMinY(data), + @"{x = %g; y = %g; width = %g; height = %g;}", NSMinX(data), NSMinY(data), NSWidth(data), NSHeight(data)]; #elif TYPE_ORDER == 4 - return [NSString stringWithFormat: @"{width = %g; height = %g}", + return [NSString stringWithFormat: @"{width = %g; height = %g;}", data.width, data.height]; #endif } diff --git a/Source/NSCharacterSet.m b/Source/NSCharacterSet.m index 4f8762690..ef6535685 100644 --- a/Source/NSCharacterSet.m +++ b/Source/NSCharacterSet.m @@ -28,6 +28,7 @@ #include static NSString* NSCharacterSet_PATH = @"NSCharacterSets"; + static NSString* gnustep_libdir = #ifdef GNUSTEP_INSTALL_LIBDIR @GNUSTEP_INSTALL_LIBDIR; @@ -80,12 +81,12 @@ static NSLock* cache_lock = nil; path = [gstep_base_bundle pathForResource:setname ofType:@"dat" inDirectory:NSCharacterSet_PATH]; - /* This is for testing purposes */ + /* This is for testing purposes only! Look in uninstalled dir */ if (path == nil || [path length] == 0) { - path = [gstep_base_bundle pathForResource:setname - ofType:@"dat" - inDirectory:@"../NSCharacterSets"]; + path = [@"../NSCharacterSets" stringByAppendingPathComponent: + setname]; + path = [path stringByAppendingPathExtension: @"dat"]; } if (path == nil || [path length] == 0) diff --git a/Source/NSDictionary.m b/Source/NSDictionary.m index d9a3a02aa..d970e103a 100644 --- a/Source/NSDictionary.m +++ b/Source/NSDictionary.m @@ -244,28 +244,14 @@ static Class NSMutableDictionary_concrete_class; - (NSString*) description { - id desc; - id keyenum = [self keyEnumerator]; - id key; - - desc = [NSMutableString stringWithCapacity: 2]; - [desc appendString: @"{"]; - while ((key = [keyenum nextObject])) - { - /* I wish appendString: returned self*/ - [desc appendString: [key description]]; - [desc appendString: @" = "]; - [desc appendString: [[self objectForKey: key] description]]; - [desc appendString: @"; "]; - } - [desc appendString: @"}"]; - return desc; + /* This method is overridden by [Dictionary -description] */ + return nil; } - (NSString*) descriptionWithIndent: (unsigned)level { - return [NSString stringWithFormat:@"%*s%s", - level, "", [[self description] cStringNoCopy]]; + /* This method is overridden by [Dictionary -descriptionWithIndent:] */ + return nil; } - (NSArray*) allKeys diff --git a/Source/NSNumber.m b/Source/NSNumber.m index e663366e2..69e8e97c3 100644 --- a/Source/NSNumber.m +++ b/Source/NSNumber.m @@ -165,6 +165,22 @@ autorelease]; } ++ valueFromString: (NSString *)string +{ + /* FIXME: implement this better */ + const char *str; + + str = [string cString]; + if (strchr(str, '.') >= 0 || strchr(str, 'e') >= 0 + || strchr(str, 'E') >= 0) + return [NSNumber numberWithDouble: atof(str)]; + else if (strchr(str, '-') >= 0) + return [NSNumber numberWithInt: atoi(str)]; + else + return [NSNumber numberWithUnsignedInt: atoi(str)]; + return [NSNumber numberWithInt: 0]; +} + /* All the rest of these methods must be implemented by a subclass */ - (BOOL)boolValue { diff --git a/Source/NSString.m b/Source/NSString.m index 334089295..7cb965671 100644 --- a/Source/NSString.m +++ b/Source/NSString.m @@ -404,6 +404,8 @@ handle_printf_atsign (FILE *stream, va_arg(arg_list, int); break; case 's': + if (*(spec_pos - 1) == '*') + va_arg(arg_list, int*); va_arg(arg_list, char*); break; case 'f': case 'e': case 'E': case 'g': case 'G': @@ -1672,7 +1674,7 @@ else int len, count; /* xxx check to make sure aRange is within self; raise NSStringBoundsError */ - assert(aRange.location + aRange.length <= [self cStringLength]); + assert(NSMaxRange(aRange) <= [self cStringLength]); if (maxLength < aRange.length) { len = maxLength; @@ -1904,7 +1906,7 @@ else } /* Returns a new string with the path component given in aString - appended to the receiver. Raises an exception if aString contains + appended to the receiver. Raises an exception if aString starts with a '/'. Checks the receiver to see if the last letter is a '/', if it is not, a '/' is appended before appending aString */ - (NSString*) stringByAppendingPathComponent: (NSString*)aString @@ -1916,7 +1918,7 @@ else return [[self copy] autorelease]; range = [aString rangeOfString:@"/"]; - if (range.length != 0) + if (range.length != 0 && range.location == 0) [NSException raise: NSGenericException format: @"attempt to append illegal path component"]; @@ -1931,7 +1933,7 @@ else } /* Returns a new string with the path extension given in aString - appended to the receiver. Raises an exception if aString contains + appended to the receiver. Raises an exception if aString starts with a '.'. Checks the receiver to see if the last letter is a '.', if it is not, a '.' is appended before appending aString */ - (NSString*) stringByAppendingPathExtension: (NSString*)aString @@ -1943,7 +1945,7 @@ else return [[self copy] autorelease]; range = [aString rangeOfString:@"."]; - if (range.length != 0) + if (range.length != 0 && range.location == 0) [NSException raise: NSGenericException format: @"attempt to append illegal path extension"]; diff --git a/Source/NSValue.m b/Source/NSValue.m index ff5104bb7..5aed67b98 100644 --- a/Source/NSValue.m +++ b/Source/NSValue.m @@ -24,6 +24,7 @@ #include #include #include +#include /* NSValueDecoder is a Class whose only purpose is to decode coded NSValue objects. The only method(s) that should ever be called are +newWithCoder: @@ -160,6 +161,40 @@ autorelease]; } ++ valueFromString: (NSString *)string +{ + NSDictionary *dict = [string propertyList]; + if (!dict) + return nil; + + if ([dict objectForKey: @"width"] && [dict objectForKey: @"x"]) + { + NSRect rect; + rect = NSMakeRect([[dict objectForKey: @"x"] floatValue], + [[dict objectForKey: @"y"] floatValue], + [[dict objectForKey: @"width"] floatValue], + [[dict objectForKey: @"height"] floatValue]); + return [NSValue valueWithRect: rect]; + } + else if ([dict objectForKey: @"width"]) + { + NSSize size; + size = NSMakeSize([[dict objectForKey: @"width"] floatValue], + [[dict objectForKey: @"height"] floatValue]); + return [NSValue valueWithSize: size]; + } + else if ([dict objectForKey: @"x"]) + { + NSPoint point; + point = NSMakePoint([[dict objectForKey: @"x"] floatValue], + [[dict objectForKey: @"y"] floatValue]); + return [NSValue valueWithPoint: point]; + } + return nil; +} + + + // Accessing Data /* All the rest of these methods must be implemented by a subclass */ - (void)getValue:(void *)value