mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-21 04:32:03 +00:00
Path handling fixes.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@13553 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
902370421e
commit
fbf5e99950
4 changed files with 484 additions and 310 deletions
|
@ -1,3 +1,12 @@
|
|||
2002-04-29 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/NSFileManager.m: Standardise handling for windoze drive
|
||||
specifiers in file paths.
|
||||
* Source/NSUser.m: Use ([-stringWithFileSystemRepresentation:length:])
|
||||
when importing file names.
|
||||
* Source/NSString.m: Update all path handling methods for windoze
|
||||
changes. Fix several bugs where we did not conform to documentation.
|
||||
|
||||
2002-04-28 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/NSFileManager.m: Port
|
||||
|
|
|
@ -316,7 +316,8 @@ static NSFileManager* defaultManager = nil;
|
|||
{
|
||||
if (cur == len)
|
||||
{
|
||||
ASSIGN(_lastError, @"Could not create directory - already exists");
|
||||
ASSIGN(_lastError,
|
||||
@"Could not create directory - already exists");
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
@ -1307,6 +1308,16 @@ static NSFileManager* defaultManager = nil;
|
|||
|
||||
// Converting file-system representations
|
||||
|
||||
/**
|
||||
* Convert from OpenStep internal path format (unix-style) to a string in
|
||||
* the local filesystem format, suitable for passing to system functions.<br />
|
||||
* Under unix, this simply standardizes the path and converts to a
|
||||
* C string.<br />
|
||||
* Under windoze, this attempts to use local conventions to convert to a
|
||||
* windows path. In GNUstep, the conventional unix syntax '~user/...' can
|
||||
* be used to indicate a windoze drive specification by using the drive
|
||||
* letter in place of the username.
|
||||
*/
|
||||
- (const char*) fileSystemRepresentationWithPath: (NSString*)path
|
||||
{
|
||||
#ifdef __MINGW__
|
||||
|
@ -1314,15 +1325,25 @@ static NSFileManager* defaultManager = nil;
|
|||
* If path is in Unix format, transmogrify it so Windows functions
|
||||
* can handle it
|
||||
*/
|
||||
NSString *newpath = path;
|
||||
const char *c_path = [path cString];
|
||||
int l = [path length];
|
||||
NSString *newpath;
|
||||
const char *c_path;
|
||||
int l;
|
||||
|
||||
path = [path stringByStandardizingPath];
|
||||
newpath = path;
|
||||
c_path = [path cString];
|
||||
l = strlen(c_path);
|
||||
|
||||
if (c_path == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (l >= 3 && c_path[0] == '/' && c_path[1] == '/' && isalpha(c_path[2]))
|
||||
if (l >= 3 && c_path[0] == '~' && c_path[2] == '/' && isalpha(c_path[1]))
|
||||
{
|
||||
newpath = [NSString stringWithFormat: @"%c:%s", c_path[1],
|
||||
&c_path[2]];
|
||||
}
|
||||
else if (l >= 3 && c_path[0] == '/' && c_path[1] == '/' && isalpha(c_path[2]))
|
||||
{
|
||||
if (l == 3 || c_path[3] == '/')
|
||||
{
|
||||
|
@ -1387,16 +1408,25 @@ static NSFileManager* defaultManager = nil;
|
|||
newpath = [newpath stringByReplacingString: @"/" withString: @"\\"];
|
||||
return [newpath cString];
|
||||
#else
|
||||
return [path cString];
|
||||
return [[path stringByStandardizingPath] cString];
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* This method converts from a local system specific filename representation
|
||||
* to the internal OpenStep representation (unix-style). This should be used
|
||||
* whenever a filename is read in from the local system.<br />
|
||||
* In GNUstep, windoze drive specifiers are encoded in the internal path
|
||||
* using the conventuional unix syntax of '~user/...' where the drive letter
|
||||
* is used instead of a username.
|
||||
*/
|
||||
- (NSString*) stringWithFileSystemRepresentation: (const char*)string
|
||||
length: (unsigned int)len
|
||||
{
|
||||
#ifdef __MINGW__
|
||||
char buf[len + 20];
|
||||
unsigned i;
|
||||
unsigned j;
|
||||
|
||||
/*
|
||||
* If path is in Windows format, transmogrify it so Unix functions
|
||||
|
@ -1409,57 +1439,56 @@ static NSFileManager* defaultManager = nil;
|
|||
if (len >= 2 && string[1] == ':' && isalpha(string[0]))
|
||||
{
|
||||
/*
|
||||
* Convert '<driveletter>:' to '/<driveletter>/' sequences on MSYS
|
||||
* or '/cygdrive/<driveletter>/' on CYGWIN
|
||||
* Convert '<driveletter>:' to '~<driveletter>/' sequences.
|
||||
*/
|
||||
#ifdef __CYGWIN__
|
||||
strcpy(buf, "/cygdrive/");
|
||||
buf[10] = string[0];
|
||||
buf[11] = '/';
|
||||
string -= 9;
|
||||
len += 9;
|
||||
i = 11;
|
||||
#else
|
||||
buf[0] = '/';
|
||||
buf[0] = '~';
|
||||
buf[1] = string[0];
|
||||
buf[2] = '/';
|
||||
string--;
|
||||
len++;
|
||||
i = 3;
|
||||
#endif
|
||||
}
|
||||
#ifdef __CYGWIN__
|
||||
else if (len > 9 && strncmp(string, "/cygdrive/", 10) == 0)
|
||||
{
|
||||
buf[0] = '~';
|
||||
string += 9;
|
||||
len -= 9;
|
||||
i = 1;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
i = 0;
|
||||
}
|
||||
/*
|
||||
* Convert backslashes to slashes.
|
||||
* Convert backslashes to slashes, colaescing adjacent slashses.
|
||||
* Also elide '/./' sequences, because we can do so efficiently.
|
||||
*/
|
||||
j = i;
|
||||
while (i < len)
|
||||
{
|
||||
if (string[i] == '\\')
|
||||
{
|
||||
buf[i] = '/';
|
||||
if (j == 0 || buf[j-1] != '/')
|
||||
{
|
||||
if (j > 2 && buf[j-2] == '/' && buf[j-1] == '.')
|
||||
{
|
||||
j--;
|
||||
}
|
||||
else
|
||||
{
|
||||
buf[i] = string[i];
|
||||
buf[j++] = '/';
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
buf[j++] = string[i];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
/*
|
||||
* Coalesce multiple slashes into a single one.
|
||||
*/
|
||||
for (i = 1; i < len; i++)
|
||||
{
|
||||
if (buf[i] == '/' && buf[i - 1] == '/')
|
||||
{
|
||||
len--;
|
||||
memmove(&buf[i], &buf[i+1], len - i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
return [NSString stringWithCString: buf length: len];
|
||||
return [NSString stringWithCString: buf length: j];
|
||||
#endif
|
||||
return [NSString stringWithCString: string length: len];
|
||||
}
|
||||
|
|
|
@ -196,18 +196,12 @@ static void setupWhitespace()
|
|||
static id GSPropertyList(NSString *string);
|
||||
static id GSPropertyListFromStringsFormat(NSString *string);
|
||||
|
||||
#if defined(__MINGW__)
|
||||
static unichar pathSepChar = (unichar)'\\';
|
||||
static NSString *pathSepString = @"\\";
|
||||
static NSString *rootPath = @"C:\\";
|
||||
#else
|
||||
static unichar pathSepChar = (unichar)'/';
|
||||
static NSString *pathSepString = @"/";
|
||||
static NSString *rootPath = @"/";
|
||||
#endif
|
||||
|
||||
static NSCharacterSet *myPathSeps = nil;
|
||||
/*
|
||||
* The pathSeps character set is used for parsing paths ... it *must*
|
||||
* contain the '/' character, which is the internal path separator,
|
||||
* and *may* contain additiona system specific separators.
|
||||
*
|
||||
* We can't have a 'pathSeps' variable initialized in the +initialize
|
||||
* method 'cos that would cause recursion.
|
||||
*/
|
||||
|
@ -2494,79 +2488,102 @@ handle_printf_atsign (FILE *stream,
|
|||
return YES;
|
||||
}
|
||||
|
||||
/* Returns a new string containing the last path component of the receiver. The
|
||||
path component is any substring after the last '/' character. If the last
|
||||
character is a '/', then the substring before the last '/', but after the
|
||||
second-to-last '/' is returned. Returns the receiver if there are no '/'
|
||||
characters. Returns the null string if the receiver only contains a '/'
|
||||
character. */
|
||||
/**
|
||||
* Returns a string containing the last path component of the receiver.<br />
|
||||
* The path component is the last non-empty substring delimited by the ends
|
||||
* of the string or by path * separator ('/') characters.<br />
|
||||
* If the receiver is an empty string, it is simply returned.<br />
|
||||
* If there are no non-empty substrings, the root string is returned.
|
||||
*/
|
||||
- (NSString*) lastPathComponent
|
||||
{
|
||||
NSRange range;
|
||||
NSString *substring = nil;
|
||||
NSString *substring;
|
||||
unsigned int l = [self length];
|
||||
|
||||
range = [self rangeOfCharacterFromSet: pathSeps() options: NSBackwardsSearch];
|
||||
if (l == 0)
|
||||
{
|
||||
substring = self; // self is empty
|
||||
}
|
||||
else
|
||||
{
|
||||
NSRange range;
|
||||
|
||||
range = [self rangeOfCharacterFromSet: pathSeps()
|
||||
options: NSBackwardsSearch];
|
||||
if (range.length == 0)
|
||||
{
|
||||
substring = AUTORELEASE([self copy]);
|
||||
substring = self; // No '/' in self
|
||||
}
|
||||
else if (range.location == ([self length] - 1))
|
||||
else if (range.location == (l - 1))
|
||||
{
|
||||
if (range.location == 0)
|
||||
{
|
||||
substring = @"";
|
||||
substring = self; // Just '/'
|
||||
}
|
||||
else
|
||||
{
|
||||
substring = [[self substringToIndex: range.location]
|
||||
lastPathComponent];
|
||||
l = range.location;
|
||||
while (l > 0 && [self characterAtIndex: l - 1] == '/')
|
||||
{
|
||||
l--;
|
||||
}
|
||||
if (l > 0)
|
||||
{
|
||||
substring = [[self substringToIndex: l] lastPathComponent];
|
||||
}
|
||||
else
|
||||
{
|
||||
substring = @"/"; // Multiple '/' characters.
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
substring = [self substringFromIndex: range.location + 1];
|
||||
}
|
||||
}
|
||||
|
||||
return substring;
|
||||
}
|
||||
|
||||
/* Returns a new string containing the path extension of the receiver. The
|
||||
path extension is a suffix on the last path component which starts with
|
||||
a '.' (for example .tiff is the pathExtension for /foo/bar.tiff). Returns
|
||||
a null string if no such extension exists. */
|
||||
/**
|
||||
* Returns a new string containing the path extension of the receiver.<br />
|
||||
* The path extension is a suffix on the last path component which starts
|
||||
* with the extension separator (a '.') (for example .tiff is the
|
||||
* pathExtension for /foo/bar.tiff).<br />
|
||||
* Returns an empty string if no such extension exists.
|
||||
*/
|
||||
- (NSString*) pathExtension
|
||||
{
|
||||
NSRange range;
|
||||
NSString *substring = nil;
|
||||
NSString *substring;
|
||||
unsigned int length = [self length];
|
||||
|
||||
range = [self rangeOfString: @"." options: NSBackwardsSearch];
|
||||
/*
|
||||
* Step past trailing path separators.
|
||||
*/
|
||||
while (length > 1 && pathSepMember([self characterAtIndex: length-1]) == YES)
|
||||
{
|
||||
length--;
|
||||
}
|
||||
range = NSMakeRange(0, length);
|
||||
range = [self rangeOfString: @"." options: NSBackwardsSearch range: range];
|
||||
if (range.length == 0)
|
||||
{
|
||||
substring = nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
NSRange range2 = [self rangeOfCharacterFromSet: pathSeps()
|
||||
options: NSBackwardsSearch];
|
||||
|
||||
if (range2.length > 0 && range.location < range2.location)
|
||||
{
|
||||
substring = nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
substring = [self substringFromIndex: range.location + 1];
|
||||
}
|
||||
}
|
||||
|
||||
if (substring == nil)
|
||||
{
|
||||
substring = @"";
|
||||
}
|
||||
else
|
||||
{
|
||||
range.location++;
|
||||
range.length = length - range.location;
|
||||
substring = [self substringFromRange: range];
|
||||
}
|
||||
|
||||
return substring;
|
||||
}
|
||||
|
||||
/* 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.
|
||||
* Removes trailing separators and multiple separators.
|
||||
*/
|
||||
|
@ -2577,11 +2594,15 @@ handle_printf_atsign (FILE *stream,
|
|||
unichar buf[length+aLength+1];
|
||||
|
||||
[self getCharacters: buf];
|
||||
while (length > 1 && pathSepMember(buf[length-1]) == YES)
|
||||
{
|
||||
length--;
|
||||
}
|
||||
if (aLength > 0)
|
||||
{
|
||||
if (length > 0)
|
||||
if (length > 0 && pathSepMember(buf[length-1]) == NO)
|
||||
{
|
||||
buf[length++] = pathSepChar;
|
||||
buf[length++] = '/';
|
||||
}
|
||||
[aString getCharacters: &buf[length]];
|
||||
}
|
||||
|
@ -2592,14 +2613,8 @@ handle_printf_atsign (FILE *stream,
|
|||
}
|
||||
if (length > 0)
|
||||
{
|
||||
#if defined(__MINGW__)
|
||||
#define _PATH_SEARCH_END 1
|
||||
#else
|
||||
#define _PATH_SEARCH_END 0
|
||||
#endif
|
||||
aLength = length - 1;
|
||||
while (aLength > _PATH_SEARCH_END)
|
||||
#undef _PATH_SEARCH_END
|
||||
while (aLength > 0)
|
||||
{
|
||||
if (pathSepMember(buf[aLength]) == YES)
|
||||
{
|
||||
|
@ -2620,42 +2635,91 @@ handle_printf_atsign (FILE *stream,
|
|||
return [NSStringClass stringWithCharacters: buf length: length];
|
||||
}
|
||||
|
||||
/* Returns a new string with the path extension given in aString
|
||||
appended to the receiver.
|
||||
A '.' is appended before appending aString */
|
||||
/**
|
||||
* Returns a new string with the path extension given in aString
|
||||
* appended to the receiver after the extensionSeparator ('.').<br />
|
||||
* If the receiver has trailing '/' characters which are not part of the
|
||||
* root directory, those '/' characters are stripped before the extension
|
||||
* separator is added.
|
||||
*/
|
||||
- (NSString*) stringByAppendingPathExtension: (NSString*)aString
|
||||
{
|
||||
if ([aString length] == 0)
|
||||
{
|
||||
return [self stringByAppendingString: @"."];
|
||||
}
|
||||
else
|
||||
return [self stringByAppendingFormat: @".%@", aString];
|
||||
{
|
||||
unsigned length = [self length];
|
||||
unsigned len = length;
|
||||
NSString *base = self;
|
||||
|
||||
/*
|
||||
* Step past trailing path separators.
|
||||
*/
|
||||
while (len > 1 && pathSepMember([self characterAtIndex: len-1]) == YES)
|
||||
{
|
||||
len--;
|
||||
}
|
||||
if (length != len)
|
||||
{
|
||||
NSRange range = NSMakeRange(0, len);
|
||||
|
||||
base = [base substringFromRange: range];
|
||||
}
|
||||
return [base stringByAppendingFormat: @".%@", aString];
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns a new string with the last path component removed from the
|
||||
receiver. See lastPathComponent for a definition of a path component */
|
||||
/**
|
||||
* Returns a new string with the last path component (including any final
|
||||
* path separators) removed from the receiver.<br />
|
||||
* A string without a path component other than the root is returned
|
||||
* without alteration.<br />
|
||||
* See -lastPathComponent for a definition of a path component.
|
||||
*/
|
||||
- (NSString*) stringByDeletingLastPathComponent
|
||||
{
|
||||
NSRange range;
|
||||
NSString *substring;
|
||||
unsigned int length = [self length];
|
||||
|
||||
range = [self rangeOfString: [self lastPathComponent]
|
||||
options: NSBackwardsSearch];
|
||||
/*
|
||||
* Step past trailing path separators.
|
||||
*/
|
||||
while (length > 1 && pathSepMember([self characterAtIndex: length-1]) == YES)
|
||||
{
|
||||
length--;
|
||||
}
|
||||
range = NSMakeRange(0, length);
|
||||
|
||||
/*
|
||||
* Locate path separator preceeding last path component.
|
||||
*/
|
||||
range = [self rangeOfCharacterFromSet: pathSeps()
|
||||
options: NSBackwardsSearch
|
||||
range: range];
|
||||
if (range.length == 0)
|
||||
substring = AUTORELEASE([self copy]);
|
||||
else if (range.location == 0)
|
||||
{
|
||||
substring = @"";
|
||||
else if (range.location > 1)
|
||||
substring = [self substringToIndex: range.location-1];
|
||||
}
|
||||
else if (range.location == 0)
|
||||
{
|
||||
substring = @"/";
|
||||
}
|
||||
else
|
||||
substring = pathSepString;
|
||||
{
|
||||
substring = [self substringToIndex: range.location];
|
||||
}
|
||||
return substring;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a new string with the path extension removed from the receiver.
|
||||
/**
|
||||
* Returns a new string with the path extension removed from the receiver.<br />
|
||||
* Strips any trailing path separators before checking for the extension
|
||||
* separator.
|
||||
* separator.<br />
|
||||
* Does not consider a string starting with the extension separator ('.') to
|
||||
* be a path extension.
|
||||
*/
|
||||
- (NSString*) stringByDeletingPathExtension
|
||||
{
|
||||
|
@ -2697,17 +2761,27 @@ handle_printf_atsign (FILE *stream,
|
|||
return substring;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string created by expanding the initial tilde ('~') and any
|
||||
* following username to be the home directory of the current user or the
|
||||
* named user.<br />
|
||||
* Returns the receiver if it was not possible to expand it.
|
||||
*/
|
||||
- (NSString*) stringByExpandingTildeInPath
|
||||
{
|
||||
NSString *homedir;
|
||||
NSRange first_slash_range;
|
||||
|
||||
if ([self length] == 0)
|
||||
return AUTORELEASE([self copy]);
|
||||
{
|
||||
return self;
|
||||
}
|
||||
if ([self characterAtIndex: 0] != 0x007E)
|
||||
return AUTORELEASE([self copy]);
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
first_slash_range = [self rangeOfString: pathSepString];
|
||||
first_slash_range = [self rangeOfCharacterFromSet: pathSeps()];
|
||||
|
||||
if (first_slash_range.location != 1)
|
||||
{
|
||||
|
@ -2733,19 +2807,35 @@ handle_printf_atsign (FILE *stream,
|
|||
/* It is of the form `~/blah/...' */
|
||||
homedir = NSHomeDirectory ();
|
||||
}
|
||||
|
||||
if (homedir != nil)
|
||||
{
|
||||
return [NSStringClass stringWithFormat: @"%@%@", homedir,
|
||||
[self substringFromIndex: first_slash_range.location]];
|
||||
}
|
||||
else
|
||||
{
|
||||
return self;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string where a prefix of the current user's home directory is
|
||||
* abbreviated by '~', or returns the receiver if it was not found to have
|
||||
* the home directory as a prefix.
|
||||
*/
|
||||
- (NSString*) stringByAbbreviatingWithTildeInPath
|
||||
{
|
||||
NSString *homedir = NSHomeDirectory ();
|
||||
|
||||
if (![self hasPrefix: homedir])
|
||||
return AUTORELEASE([self copy]);
|
||||
|
||||
return [NSStringClass stringWithFormat: @"~%c%@", (char)pathSepChar,
|
||||
{
|
||||
return self;
|
||||
}
|
||||
if ([self length] == [homedir length])
|
||||
{
|
||||
return @"~";
|
||||
}
|
||||
return [NSStringClass stringWithFormat: @"~/%@",
|
||||
[self substringFromIndex: [homedir length] + 1]];
|
||||
}
|
||||
|
||||
|
@ -2939,19 +3029,8 @@ handle_printf_atsign (FILE *stream,
|
|||
if (r.location + r.length + 1 <= length
|
||||
&& pathSepMember((*caiImp)(s, caiSel, r.location + 1)) == YES)
|
||||
{
|
||||
#if defined(__MINGW__)
|
||||
if (r.location)
|
||||
{
|
||||
[s deleteCharactersInRange: r];
|
||||
}
|
||||
else
|
||||
{
|
||||
r.location++;
|
||||
}
|
||||
#else
|
||||
[s deleteCharactersInRange: r];
|
||||
#endif /* (__MINGW__) */
|
||||
}
|
||||
else if (r.location + r.length + 2 <= length
|
||||
&& (*caiImp)(s, caiSel, r.location + 1) == (unichar)'.'
|
||||
&& pathSepMember((*caiImp)(s, caiSel, r.location + 2)) == YES)
|
||||
|
@ -3062,6 +3141,10 @@ handle_printf_atsign (FILE *stream,
|
|||
return blen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenates the strings in the components array placing a path
|
||||
* separator between each one and returns the result.
|
||||
*/
|
||||
+ (NSString*) pathWithComponents: (NSArray*)components
|
||||
{
|
||||
NSString *s;
|
||||
|
@ -3074,9 +3157,9 @@ handle_printf_atsign (FILE *stream,
|
|||
return @"";
|
||||
}
|
||||
s = [components objectAtIndex: 0];
|
||||
if ([s length] == 0 || [s isEqualToString: pathSepString] == YES)
|
||||
if ([s length] == 0)
|
||||
{
|
||||
s = rootPath;
|
||||
s = @"/";
|
||||
}
|
||||
for (i = 1; i < c; i++)
|
||||
{
|
||||
|
@ -3085,48 +3168,39 @@ handle_printf_atsign (FILE *stream,
|
|||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returs YES if the receiver represents an absolute path ... ie if it begins
|
||||
* with a '/' or a '~'<br />
|
||||
* Returns NO otherwise.
|
||||
*/
|
||||
- (BOOL) isAbsolutePath
|
||||
{
|
||||
unichar c;
|
||||
|
||||
if ([self length] == 0)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
c = [self characterAtIndex: 0];
|
||||
#if defined(__MINGW__)
|
||||
if ([self indexOfString: @":"] == NSNotFound)
|
||||
{
|
||||
const char *cpath = [self fileSystemRepresentation];
|
||||
|
||||
if (isalpha(cpath[0]) && cpath[1] == ':')
|
||||
if (isalpha(c) && [self indexOfString: @":"] == 1)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
else if (cpath[0] == cpath[1]
|
||||
&& (cpath[0] == '/' || cpath[0] == '\\'))
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
#else
|
||||
{
|
||||
unichar c = [self characterAtIndex: 0];
|
||||
|
||||
#endif
|
||||
if (c == (unichar)'/' || c == (unichar)'~')
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return NO;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path components of the reciever separated into an array.<br />
|
||||
* If the receiver begins with a '/' character then that is used as the
|
||||
* first element in the array.<br />
|
||||
* Empty components are removed.
|
||||
*/
|
||||
- (NSArray*) pathComponents
|
||||
{
|
||||
NSMutableArray *a;
|
||||
|
@ -3136,7 +3210,7 @@ handle_printf_atsign (FILE *stream,
|
|||
{
|
||||
return [NSArray array];
|
||||
}
|
||||
a = [[self componentsSeparatedByString: pathSepString] mutableCopy];
|
||||
a = [[self componentsSeparatedByString: @"/"] mutableCopy];
|
||||
if ([a count] > 0)
|
||||
{
|
||||
int i;
|
||||
|
@ -3148,7 +3222,7 @@ handle_printf_atsign (FILE *stream,
|
|||
*/
|
||||
if ([[a objectAtIndex: 0] length] == 0)
|
||||
{
|
||||
[a replaceObjectAtIndex: 0 withObject: pathSepString];
|
||||
[a replaceObjectAtIndex: 0 withObject: @"/"];
|
||||
}
|
||||
/*
|
||||
* Similarly if the path ended with a path separator (other than the
|
||||
|
@ -3158,7 +3232,7 @@ handle_printf_atsign (FILE *stream,
|
|||
{
|
||||
if ([self length] > 1)
|
||||
{
|
||||
[a replaceObjectAtIndex: [a count]-1 withObject: pathSepString];
|
||||
[a replaceObjectAtIndex: [a count]-1 withObject: @"/"];
|
||||
}
|
||||
}
|
||||
/* Any empty path components must be removed. */
|
||||
|
@ -3175,6 +3249,10 @@ handle_printf_atsign (FILE *stream,
|
|||
return AUTORELEASE(r);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of strings made by appending the values in paths
|
||||
* to the receiver.
|
||||
*/
|
||||
- (NSArray*) stringsByAppendingPaths: (NSArray*)paths
|
||||
{
|
||||
NSMutableArray *a;
|
||||
|
@ -3187,10 +3265,6 @@ handle_printf_atsign (FILE *stream,
|
|||
{
|
||||
NSString *s = [paths objectAtIndex: i];
|
||||
|
||||
while ([s isAbsolutePath])
|
||||
{
|
||||
s = [s substringFromIndex: 1];
|
||||
}
|
||||
s = [self stringByAppendingPathComponent: s];
|
||||
[a addObject: s];
|
||||
}
|
||||
|
|
100
Source/NSUser.m
100
Source/NSUser.m
|
@ -64,6 +64,30 @@ static NSString *gnustep_system_root = nil; /* GNUSTEP_SYSTEM_ROOT */
|
|||
static void setupPathNames();
|
||||
static NSString *userDirectory(NSString *name, BOOL defaults);
|
||||
|
||||
static NSString*
|
||||
ImportPath(NSString *s, const char *c)
|
||||
{
|
||||
static NSFileManager *mgr = nil;
|
||||
const char *ptr = c;
|
||||
unsigned len;
|
||||
|
||||
if (mgr == nil)
|
||||
{
|
||||
mgr = [NSFileManager defaultManager];
|
||||
RETAIN(mgr);
|
||||
}
|
||||
if (ptr == 0)
|
||||
{
|
||||
if (s == nil)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
ptr = [s cString];
|
||||
}
|
||||
len = strlen(ptr);
|
||||
return [mgr stringWithFileSystemRepresentation: ptr length: len];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the user name for this process. This method is supplied to enable
|
||||
* setuid programs to run properly as the user indicated by their effective
|
||||
|
@ -227,7 +251,6 @@ NSHomeDirectoryForUser(NSString *loginName)
|
|||
pw = getpwnam ([loginName cString]);
|
||||
if (pw == 0)
|
||||
{
|
||||
NSLog(@"Unable to locate home directory for '%@'", loginName);
|
||||
s = nil;
|
||||
}
|
||||
else
|
||||
|
@ -235,7 +258,6 @@ NSHomeDirectoryForUser(NSString *loginName)
|
|||
s = [NSString stringWithCString: pw->pw_dir];
|
||||
}
|
||||
[gnustep_global_lock unlock];
|
||||
return s;
|
||||
#else
|
||||
/* Then environment variable HOMEPATH holds the home directory
|
||||
for the user on Windows NT; Win95 has no concept of home. */
|
||||
|
@ -247,8 +269,8 @@ NSHomeDirectoryForUser(NSString *loginName)
|
|||
stringByAppendingString: s];
|
||||
}
|
||||
[gnustep_global_lock unlock];
|
||||
return s;
|
||||
#endif
|
||||
return ImportPath(s, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -274,6 +296,7 @@ setupPathNames()
|
|||
{
|
||||
#if defined (__MINGW32__)
|
||||
NSString *systemDrive = GSStringFromWin32EnvironmentVariable("SystemDrive");
|
||||
systemDrive = ImportPath(systemDrive, 0);
|
||||
#endif
|
||||
if (gnustep_user_root == nil)
|
||||
{
|
||||
|
@ -289,6 +312,7 @@ setupPathNames()
|
|||
{
|
||||
/* Any of the following might be nil */
|
||||
gnustep_system_root = [env objectForKey: @"GNUSTEP_SYSTEM_ROOT"];
|
||||
gnustep_system_root = ImportPath(gnustep_system_root, 0);
|
||||
TEST_RETAIN (gnustep_system_root);
|
||||
if (gnustep_system_root == nil)
|
||||
{
|
||||
|
@ -298,13 +322,12 @@ setupPathNames()
|
|||
* resources. Use fprintf to avoid recursive calls.
|
||||
*/
|
||||
warned = YES;
|
||||
gnustep_system_root = [NSString stringWithCString:
|
||||
stringify(GNUSTEP_INSTALL_PREFIX)];
|
||||
gnustep_system_root
|
||||
= ImportPath(nil, stringify(GNUSTEP_INSTALL_PREFIX));
|
||||
#if defined (__MINGW32__)
|
||||
gnustep_system_root = [systemDrive stringByAppendingString:
|
||||
gnustep_system_root];
|
||||
#endif
|
||||
|
||||
RETAIN(gnustep_system_root);
|
||||
fprintf (stderr,
|
||||
"Warning - GNUSTEP_SYSTEM_ROOT is not set "
|
||||
|
@ -314,20 +337,25 @@ setupPathNames()
|
|||
if (gnustep_local_root == nil)
|
||||
{
|
||||
gnustep_local_root = [env objectForKey: @"GNUSTEP_LOCAL_ROOT"];
|
||||
gnustep_local_root = ImportPath(gnustep_local_root, 0);
|
||||
TEST_RETAIN (gnustep_local_root);
|
||||
if (gnustep_local_root == nil)
|
||||
{
|
||||
gnustep_local_root = [NSString stringWithCString:
|
||||
stringify(GNUSTEP_LOCAL_ROOT)];
|
||||
gnustep_local_root = ImportPath(nil,
|
||||
stringify(GNUSTEP_LOCAL_ROOT));
|
||||
#if defined (__MINGW32__)
|
||||
gnustep_local_root = [systemDrive stringByAppendingString:
|
||||
gnustep_local_root];
|
||||
#endif
|
||||
if ([gnustep_local_root length] == 0)
|
||||
{
|
||||
gnustep_local_root = nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
RETAIN(gnustep_local_root);
|
||||
}
|
||||
}
|
||||
if (gnustep_local_root == nil)
|
||||
{
|
||||
if ([[gnustep_system_root lastPathComponent] isEqual:
|
||||
|
@ -357,20 +385,25 @@ setupPathNames()
|
|||
{
|
||||
gnustep_network_root = [env objectForKey:
|
||||
@"GNUSTEP_NETWORK_ROOT"];
|
||||
gnustep_network_root = ImportPath(gnustep_network_root, 0);
|
||||
TEST_RETAIN (gnustep_network_root);
|
||||
if (gnustep_network_root == nil)
|
||||
{
|
||||
gnustep_network_root = [NSString stringWithCString:
|
||||
stringify(GNUSTEP_NETWORK_ROOT)];
|
||||
gnustep_network_root = ImportPath(nil,
|
||||
stringify(GNUSTEP_NETWORK_ROOT));
|
||||
#if defined (__MINGW32__)
|
||||
gnustep_network_root = [systemDrive stringByAppendingString:
|
||||
gnustep_network_root];
|
||||
#endif
|
||||
if ([gnustep_network_root length] == 0)
|
||||
{
|
||||
gnustep_network_root = nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
RETAIN(gnustep_network_root);
|
||||
}
|
||||
}
|
||||
if (gnustep_network_root == nil)
|
||||
{
|
||||
if ([[gnustep_system_root lastPathComponent] isEqual:
|
||||
|
@ -454,13 +487,13 @@ userDirectory(NSString *name, BOOL defaults)
|
|||
if (defaults == YES)
|
||||
{
|
||||
#ifdef FORCE_DEFAULTS_ROOT
|
||||
return [NSString stringWithCString: stringify(FORCE_DEFAULTS_ROOT)];
|
||||
return ImportPath(nil, stringify(FORCE_DEFAULTS_ROOT));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef FORCE_USER_ROOT
|
||||
return [NSString stringWithCString: stringify(FORCE_USER_ROOT)];
|
||||
return ImportPath(nil, stringify(FORCE_USER_ROOT));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -476,10 +509,11 @@ userDirectory(NSString *name, BOOL defaults)
|
|||
{
|
||||
NSString *root;
|
||||
|
||||
root = [NSString stringWithCString: stringify(GNUSTEP_INSTALL_PREFIX)];
|
||||
root = ImportPath(nil, stringify(GNUSTEP_INSTALL_PREFIX));
|
||||
#if defined (__MINGW32__)
|
||||
root = [GSStringFromWin32EnvironmentVariable("SystemDrive")
|
||||
stringByAppendingString: gnustep_system_root];
|
||||
root = ImportPath(root, 0);
|
||||
#endif
|
||||
file = [root stringByAppendingPathComponent: @".GNUsteprc"];
|
||||
}
|
||||
|
@ -551,7 +585,7 @@ userDirectory(NSString *name, BOOL defaults)
|
|||
path = [home stringByAppendingPathComponent: @"GNUstep"];
|
||||
}
|
||||
|
||||
return path;
|
||||
return ImportPath(path, 0);
|
||||
}
|
||||
|
||||
/** Returns an array of strings which contain paths that should be in
|
||||
|
@ -573,17 +607,31 @@ GSStandardPathPrefixes(void)
|
|||
prefixes = [env objectForKey: @"GNUSTEP_PATHPREFIX_LIST"];
|
||||
if (prefixes != nil)
|
||||
{
|
||||
unsigned c;
|
||||
|
||||
#if defined(__WIN32__)
|
||||
prefixArray = [prefixes componentsSeparatedByString: @";"];
|
||||
#else
|
||||
prefixArray = [prefixes componentsSeparatedByString: @":"];
|
||||
#endif
|
||||
if ([prefixArray count] <= 1)
|
||||
if ((c = [prefixArray count]) <= 1)
|
||||
{
|
||||
/* This probably means there was some parsing error, but who
|
||||
knows. Play it safe though... */
|
||||
prefixArray = nil;
|
||||
}
|
||||
else
|
||||
{
|
||||
NSString *a[c];
|
||||
unsigned i;
|
||||
|
||||
[prefixArray getObjects: a];
|
||||
for (i = 0; i < c; i++)
|
||||
{
|
||||
a[c] = ImportPath(a[c], 0);
|
||||
}
|
||||
prefixArray = [NSArray arrayWithObjects: a count: c];
|
||||
}
|
||||
}
|
||||
if (prefixes == nil)
|
||||
{
|
||||
|
@ -659,7 +707,7 @@ NSTemporaryDirectory(void)
|
|||
|
||||
if (GetTempPath(1024, buffer))
|
||||
{
|
||||
baseTempDirName = [NSString stringWithCString: buffer];
|
||||
baseTempDirName = ImportPath(nil, buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -678,8 +726,12 @@ NSTemporaryDirectory(void)
|
|||
baseTempDirName = [env objectForKey: @"TMP"];
|
||||
if (baseTempDirName == nil)
|
||||
{
|
||||
#if defined(__WIN32__)
|
||||
baseTempDirName = @"C:\\";
|
||||
#if defined(__MINGW__)
|
||||
#ifdef __CYGWIN__
|
||||
baseTempDirName = @"/cygdrive/c/";
|
||||
#else
|
||||
baseTempDirName = @"/c/";
|
||||
#endif
|
||||
#else
|
||||
baseTempDirName = @"/tmp";
|
||||
#endif
|
||||
|
@ -752,11 +804,21 @@ NSOpenStepRootDirectory(void)
|
|||
root = [[[NSProcessInfo processInfo] environment]
|
||||
objectForKey: @"GNUSTEP_ROOT"];
|
||||
if (root == nil)
|
||||
{
|
||||
#if defined(__MINGW__)
|
||||
root = @"C:\\";
|
||||
#ifdef __CYGWIN__
|
||||
root = @"/cygdrive/c/";
|
||||
#else
|
||||
root = @"/c/";
|
||||
#endif
|
||||
#else
|
||||
root = @"/";
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
root = ImportPath(root, 0);
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue