Fixed `Caveats' comment.

([NSString -commonPrefixWithString:options:]): Method implemeneted.
([NSString -capitalizedString]): Method implemented.
([NSString -lowercaseString]): Method implemented.
([NSString -uppercaseString]): Method implemented.
([NSString -stringByExpandingTildeInPath]): Method implemented.
([NSString -stringByAbbreviatingWithTildeInPath]): Method implemented.
([NSString -stringByStandardizingPath]): Method implemented.
([NSString -_cStringContents]): Method removed.  All callers changed
to use -cStringNoCopy.
([NSString -objectAtIndex:]): Method removed.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1955 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
mccallum 1996-11-24 21:04:24 +00:00
parent cdd4c88577
commit 9c1198ff9f

View file

@ -23,14 +23,11 @@
/* Caveats: /* Caveats:
Many method unimplemented.
Only supports C Strings. Some implementations will need to be Only supports C Strings. Some implementations will need to be
changed when we get other string backing classes. changed when we get other string backing classes.
Does not support all justification directives for `%@' in format strings Does not support all justification directives for `%@' in format strings
on non-GNU-libc systems. on non-GNU-libc systems.
*/ */
#include <gnustep/base/preface.h> #include <gnustep/base/preface.h>
@ -41,9 +38,9 @@
#include <Foundation/NSException.h> #include <Foundation/NSException.h>
#include <Foundation/NSValue.h> #include <Foundation/NSValue.h>
#include <Foundation/NSDictionary.h> #include <Foundation/NSDictionary.h>
#include <Foundation/NSUserDefaults.h>
#include <gnustep/base/IndexedCollection.h> #include <gnustep/base/IndexedCollection.h>
#include <gnustep/base/IndexedCollectionPrivate.h> #include <gnustep/base/IndexedCollectionPrivate.h>
#include <gnustep/base/behavior.h>
#include <limits.h> #include <limits.h>
#include <string.h> // for strstr() #include <string.h> // for strstr()
#include <sys/stat.h> #include <sys/stat.h>
@ -189,7 +186,7 @@ handle_printf_atsign (FILE *stream,
+ allocWithZone: (NSZone*)z + allocWithZone: (NSZone*)z
{ {
return NSAllocateObject([self _concreteClass], 0, z); return NSAllocateObject ([self _concreteClass], 0, z);
} }
// Creating Temporary Strings // Creating Temporary Strings
@ -408,7 +405,7 @@ handle_printf_atsign (FILE *stream,
/* xxx Change this when we have non-CString classes */ /* xxx Change this when we have non-CString classes */
- (id) initWithString: (NSString*)string - (id) initWithString: (NSString*)string
{ {
return [self initWithCString:[string _cStringContents]]; return [self initWithCString:[string cStringNoCopy]];
} }
@ -428,7 +425,7 @@ handle_printf_atsign (FILE *stream,
{ {
/* xxx raise NSException instead of assert. */ /* xxx raise NSException instead of assert. */
assert(index < [self cStringLength]); assert(index < [self cStringLength]);
return (unichar) [self _cStringContents][index]; return (unichar) [self cStringNoCopy][index];
} }
/* Inefficient. Should be overridden */ /* Inefficient. Should be overridden */
@ -468,8 +465,8 @@ handle_printf_atsign (FILE *stream,
{ {
unsigned len = [self cStringLength]; unsigned len = [self cStringLength];
char *s = alloca(len + [aString cStringLength] + 1); char *s = alloca(len + [aString cStringLength] + 1);
s = strcpy(s, [self _cStringContents]); s = strcpy(s, [self cStringNoCopy]);
strcpy(s + len, [aString _cStringContents]); strcpy(s + len, [aString cStringNoCopy]);
return [NSString stringWithCString:s]; return [NSString stringWithCString:s];
} }
@ -733,8 +730,8 @@ handle_printf_atsign (FILE *stream,
/* xxx only handles C-string encoding */ /* xxx only handles C-string encoding */
int i, start, end, increment; int i, start, end, increment;
const char *s1 = [self _cStringContents]; const char *s1 = [self cStringNoCopy];
const char *s2 = [aString _cStringContents]; const char *s2 = [aString cStringNoCopy];
if (mask & NSBackwardsSearch) if (mask & NSBackwardsSearch)
{ {
@ -789,7 +786,7 @@ handle_printf_atsign (FILE *stream,
unsigned ret = 0; unsigned ret = 0;
unsigned ctr = 0; unsigned ctr = 0;
unsigned char_count = 0; unsigned char_count = 0;
const char *s = [self _cStringContents]; const char *s = [self cStringNoCopy];
while (*s && char_count++ < NSHashStringLength) while (*s && char_count++ < NSHashStringLength)
{ {
@ -808,7 +805,7 @@ handle_printf_atsign (FILE *stream,
- (BOOL) isEqualToString: (NSString*)aString - (BOOL) isEqualToString: (NSString*)aString
{ {
return ! strcmp([self _cStringContents], [aString _cStringContents]); return ! strcmp([self cStringNoCopy], [aString cStringNoCopy]);
} }
@ -899,8 +896,21 @@ handle_printf_atsign (FILE *stream,
- (NSString*) commonPrefixWithString: (NSString*)aString - (NSString*) commonPrefixWithString: (NSString*)aString
options: (unsigned int)mask options: (unsigned int)mask
{ {
[self notImplemented:_cmd]; /* xxx only works with CStrings */
return self; int prefix_len = 0;
const char *s1 = [self cStringNoCopy];
const char *s2 = [aString cStringNoCopy];
while (*s1 && *s2
&& ((*s1 == *s2)
|| ((mask & NSCaseInsensitiveSearch)
&& (tolower (*s1) == tolower (*s2)))))
{
s1++;
s2++;
}
return [NSString stringWithCString: s1 length: prefix_len];
} }
@ -908,20 +918,59 @@ handle_printf_atsign (FILE *stream,
- (NSString*) capitalizedString - (NSString*) capitalizedString
{ {
[self notImplemented:_cmd]; /* xxx only works with CStrings */
return self; char *s;
BOOL just_saw_space = YES;
for (s = strdup ([self cStringNoCopy]); *s; s++)
{
if (just_saw_space && islower(*s))
{
*s = toupper (*s);
just_saw_space = NO;
}
else if (isspace (*s))
just_saw_space = YES;
}
return [[[NSString alloc] initWithCStringNoCopy: s
length: strlen (s)
freeWhenDone: YES]
autorelease];
} }
- (NSString*) lowercaseString - (NSString*) lowercaseString
{ {
[self notImplemented:_cmd]; /* xxx only works with CStrings */
return self; char *s;
for (s = strdup ([self cStringNoCopy]); *s; s++)
{
if (isupper(*s))
*s = tolower (*s);
}
return [[[NSString alloc] initWithCStringNoCopy: s
length: strlen (s)
freeWhenDone: YES]
autorelease];
} }
- (NSString*) uppercaseString - (NSString*) uppercaseString
{ {
[self notImplemented:_cmd]; /* xxx only works with CStrings */
return self; char *s;
for (s = strdup ([self cStringNoCopy]); *s; s++)
{
if (islower(*s))
*s = toupper (*s);
}
return [[[NSString alloc] initWithCStringNoCopy: s
length: strlen (s)
freeWhenDone: YES]
autorelease];
} }
@ -981,7 +1030,7 @@ handle_printf_atsign (FILE *stream,
leftoverRange->length = aRange.length - maxLength; leftoverRange->length = aRange.length - maxLength;
} }
} }
memcpy(buffer, [self _cStringContents] + aRange.location, len); memcpy(buffer, [self cStringNoCopy] + aRange.location, len);
} }
@ -989,17 +1038,17 @@ handle_printf_atsign (FILE *stream,
- (double) doubleValue - (double) doubleValue
{ {
return atof([self _cStringContents]); return atof([self cStringNoCopy]);
} }
- (float) floatValue - (float) floatValue
{ {
return (float) atof([self _cStringContents]); return (float) atof([self cStringNoCopy]);
} }
- (int) intValue - (int) intValue
{ {
return atoi([self _cStringContents]); return atoi([self cStringNoCopy]);
} }
@ -1126,12 +1175,6 @@ handle_printf_atsign (FILE *stream,
return substring; return substring;
} }
- (NSString*) stringByAbbreviatingWithTildeInPath
{
[self notImplemented:_cmd];
return self;
}
/* Returns a new string with the path component given in aString /* Returns a new string with the path component given in aString
appended to the receiver. Assumes that aString is NOT prefixed by appended to the receiver. Assumes that aString is NOT prefixed by
a '/'. Checks the receiver to see if the last letter is a '/', if it a '/'. Checks the receiver to see if the last letter is a '/', if it
@ -1201,8 +1244,50 @@ handle_printf_atsign (FILE *stream,
- (NSString*) stringByExpandingTildeInPath - (NSString*) stringByExpandingTildeInPath
{ {
[self notImplemented:_cmd]; /* xxx only works with CStrings */
return self; const char *s = [self cStringNoCopy];
NSString *homedir;
NSRange first_slash_range;
if (s[0] != '~')
return [self copy];
first_slash_range = [self rangeOfString: @"/"];
if (first_slash_range.location != 1)
{
/* It is of the form `~username/blah/...' */
int uname_len;
NSString *uname;
if (first_slash_range.length != 0)
uname_len = first_slash_range.length - 1;
else
/* It is actually of the form `~username' */
uname_len = [self length] - 1;
uname = [self substringFromRange: ((NSRange){1, uname_len})];
homedir = NSHomeDirectoryForUser (uname);
}
else
{
/* It is of the form `~/blah/...' */
homedir = NSHomeDirectory ();
}
return [NSString stringWithFormat: @"%@%@",
homedir,
[self substringFromIndex: first_slash_range.location]];
}
- (NSString*) stringByAbbreviatingWithTildeInPath
{
NSString *homedir = NSHomeDirectory ();
if (![self hasPrefix: homedir])
return [self copy];
return [NSString stringWithFormat: @"~/%@",
[self substringFromIndex: [homedir length] + 1]];
} }
- (NSString*) stringByResolvingSymlinksInPath - (NSString*) stringByResolvingSymlinksInPath
@ -1213,8 +1298,40 @@ handle_printf_atsign (FILE *stream,
- (NSString*) stringByStandardizingPath - (NSString*) stringByStandardizingPath
{ {
[self notImplemented:_cmd]; NSMutableString *s;
return self; NSRange r;
/* Expand `~' in the path */
s = [[self stringByExpandingTildeInPath] mutableCopy];
/* Remove `/private' */
if ([s hasPrefix: @"/private"])
[s deleteCharactersInRange: ((NSRange){0,7})];
/* Condense `//' */
while ((r = [s rangeOfString: @"//"]).length)
[s deleteCharactersInRange: r];
/* Condense `/./' */
while ((r = [s rangeOfString: @"/./"]).length)
{
r.length--;
[s deleteCharactersInRange: r];
}
/* Condense `/../' */
while ((r = [s rangeOfString: @"/../"]).length)
{
NSRange r2 = {0, r.length-1};
r = [s rangeOfString: @"/"
options: NSBackwardsSearch
range: r2];
r.length += 4; /* Add the `/../' */
[s deleteCharactersInRange: r];
}
/* xxx Should we not return a mutable string? */
return s;
} }
/* NSCopying Protocol */ /* NSCopying Protocol */
@ -1251,36 +1368,15 @@ handle_printf_atsign (FILE *stream,
return [super initWithCoder:aDecoder]; return [super initWithCoder:aDecoder];
} }
- cStringNoCopy - (const char *) cStringNoCopy
{ {
[self subclassResponsibility: _cmd]; [self subclassResponsibility: _cmd];
return nil;
}
@end
@implementation NSString (NSCStringAccess)
- (const char *) _cStringContents
{
[self subclassResponsibility:_cmd];
return NULL; return NULL;
} }
@end
/* We don't actually implement (GNU) Category, in order to avoid warning
about "unimplemented methods"; they come from the behavior. */
@implementation NSString (GNUCollection)
- objectAtIndex: (unsigned)index
{
CHECK_INDEX_RANGE_ERROR(index, [self cStringLength]);
return [NSNumber numberWithChar: [self _cStringContents][index]];
}
/* The rest are handled by the class_add_behavior() call in +initialize. */
@end @end
@implementation NSMutableString @implementation NSMutableString
+ allocWithZone: (NSZone*)z + allocWithZone: (NSZone*)z
@ -1387,7 +1483,7 @@ handle_printf_atsign (FILE *stream,
/* xxx Change this when we have non-CString classes */ /* xxx Change this when we have non-CString classes */
- (void) setString: (NSString*)aString - (void) setString: (NSString*)aString
{ {
const char *s = [aString _cStringContents]; const char *s = [aString cStringNoCopy];
[self setCString:s length:strlen(s)]; [self setCString:s length:strlen(s)];
} }