Tidie some path handling stuff

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@4810 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
richard 1999-09-03 11:05:33 +00:00
parent aa2e0cc17a
commit 3cabe7ad0d
2 changed files with 41 additions and 58 deletions

View file

@ -1,3 +1,9 @@
Fri Sep 3 11:57:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* Source/NSString.m: speed up path handling a bit by caching
method for testing for path separators - also fixed appending
of path extensions and components to be according to spec.
Thu Sep 2 9:03:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk> Thu Sep 2 9:03:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
* Source/NSTask.m: exec process with argv[0] set to full path of * Source/NSTask.m: exec process with argv[0] set to full path of

View file

@ -127,6 +127,8 @@ static NSString *pathSepString = @"/";
static NSString *rootPath = @"/"; static NSString *rootPath = @"/";
#endif #endif
static BOOL (*sepMember)(NSCharacterSet*, SEL, unichar) = 0;
static NSCharacterSet *myPathSeps = nil;
/* /*
* We can't have a 'pathSeps' variable initialized in the +initialize * We can't have a 'pathSeps' variable initialized in the +initialize
* method 'cos that would cause recursion. * method 'cos that would cause recursion.
@ -134,20 +136,29 @@ static NSString *rootPath = @"/";
static NSCharacterSet* static NSCharacterSet*
pathSeps() pathSeps()
{ {
static NSCharacterSet *pathSeps = nil; if (myPathSeps == nil)
if (pathSeps == nil)
{ {
#if defined(__WIN32__) #if defined(__WIN32__)
pathSeps = [NSCharacterSet characterSetWithCharactersInString: @"/\\"]; myPathSeps = [NSCharacterSet characterSetWithCharactersInString: @"/\\"];
#else #else
pathSeps = [NSCharacterSet characterSetWithCharactersInString: @"/"]; myPathSeps = [NSCharacterSet characterSetWithCharactersInString: @"/"];
#endif #endif
RETAIN(pathSeps); RETAIN(myPathSeps);
sepMember = [myPathSeps methodForSelector: @selector(characterIsMember:)];
} }
return pathSeps; return myPathSeps;
} }
static BOOL
pathSepMember(unichar c)
{
if (sepMember == 0)
pathSeps();
return (*sepMember)(myPathSeps, @selector(characterIsMember:), c);
}
@implementation NSString @implementation NSString
@ -1770,67 +1781,33 @@ handle_printf_atsign (FILE *stream,
is not, a '/' is appended before appending aString */ is not, a '/' is appended before appending aString */
- (NSString*) stringByAppendingPathComponent: (NSString*)aString - (NSString*) stringByAppendingPathComponent: (NSString*)aString
{ {
NSRange range; unsigned length;
NSString *newstring;
if ([aString length] == 0) if ([aString length] == 0)
return AUTORELEASE([self copy]); return AUTORELEASE([self copy]);
length = [self length];
if (length == 0)
return AUTORELEASE([aString copy]);
range = [aString rangeOfCharacterFromSet: pathSeps()]; if (pathSepMember([aString characterAtIndex: 0]) == YES)
if (range.length != 0 && range.location == 0) [NSException raise: NSGenericException
[NSException raise: NSGenericException format: @"attempt to append illegal path component"];
format: @"attempt to append illegal path component"];
range = [self rangeOfCharacterFromSet: pathSeps() options: NSBackwardsSearch]; if (pathSepMember([self characterAtIndex: length-1]) == YES)
if ((range.length == 0 || range.location != [self length] - 1) return [self stringByAppendingString: aString];
&& [self length] > 0)
newstring = [self stringByAppendingString: pathSepString];
else else
newstring = self; return [self stringByAppendingFormat: @"%@%@", pathSepString, aString];
return [newstring stringByAppendingString: aString];
} }
/* Returns a new string with the path extension given in aString /* Returns a new string with the path extension given in aString
appended to the receiver. Raises an exception if aString starts with appended to the receiver.
a '.'. Checks the receiver to see if the last letter is a '.', if it A '.' is appended before appending aString */
is not, a '.' is appended before appending aString */
- (NSString*) stringByAppendingPathExtension: (NSString*)aString - (NSString*) stringByAppendingPathExtension: (NSString*)aString
{ {
NSRange range;
NSString *newstring;
if ([aString length] == 0) if ([aString length] == 0)
return AUTORELEASE([self copy]); return [self stringByAppendingString: @"."];
range = [aString rangeOfString: @"."];
if (range.length != 0 && range.location == 0)
[NSException raise: NSGenericException
format: @"attempt to append illegal path extension"];
/* This is contrary to the Foundation docs, which say explicitely that:
*
* Returns a string made by appending to the receiver an extension
* separator followed by aString. The following table illustrates the
* effect of this method on a variety of different paths, assuming that
* aString is supplied as @"tiff":
* Receiver's String Value Resulting String
* "/tmp/scratch.old" "/tmp/scratch.old.tiff"
* "/tmp/scratch." "/tmp/scratch..tiff"
* "/tmp/" "/tmp/.tiff"
* "scratch" "scratch.tiff"
*/
#if 0
range = [self rangeOfString: @"." options: NSBackwardsSearch];
if (range.length == 0 || range.location != [self length] - 1)
#endif
newstring = [self stringByAppendingString: @"."];
#if 0
else else
newstring = self; return [self stringByAppendingFormat: @".%@", aString];
#endif
return [newstring stringByAppendingString: aString];
} }
/* Returns a new string with the last path component removed from the /* Returns a new string with the last path component removed from the
@ -2091,13 +2068,13 @@ handle_printf_atsign (FILE *stream,
unichar c1 = [s characterAtIndex: r.location + 1]; unichar c1 = [s characterAtIndex: r.location + 1];
if (r.location + r.length + 1 <= length if (r.location + r.length + 1 <= length
&& [pathSeps() characterIsMember: c1]) && pathSepMember(c1) == YES)
{ {
[s deleteCharactersInRange: r]; [s deleteCharactersInRange: r];
} }
else if (r.location + r.length + 2 <= length else if (r.location + r.length + 2 <= length
&& c1 == (unichar)'.' && c1 == (unichar)'.'
&& [pathSeps() characterIsMember: [s characterAtIndex: r.location + 2]]) && pathSepMember([s characterAtIndex: r.location + 2]) == YES)
{ {
r.length++; r.length++;
[s deleteCharactersInRange: r]; [s deleteCharactersInRange: r];
@ -2129,7 +2106,7 @@ handle_printf_atsign (FILE *stream,
if (r.location + r.length + 3 <= [s length] if (r.location + r.length + 3 <= [s length]
&& [s characterAtIndex: r.location + 1] == (unichar)'.' && [s characterAtIndex: r.location + 1] == (unichar)'.'
&& [s characterAtIndex: r.location + 2] == (unichar)'.' && [s characterAtIndex: r.location + 2] == (unichar)'.'
&& [pathSeps() characterIsMember: [s characterAtIndex: r.location + 3]]) && pathSepMember([s characterAtIndex: r.location + 3]) == YES)
{ {
if (r.location > 0) if (r.location > 0)
{ {