mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 16:50:58 +00:00
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:
parent
cdd4c88577
commit
9c1198ff9f
1 changed files with 155 additions and 59 deletions
|
@ -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)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue