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:
Richard Frith-Macdonald 2002-04-29 12:20:08 +00:00
parent 050fdde7c8
commit 8136200632
4 changed files with 484 additions and 310 deletions

View file

@ -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

View file

@ -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[j++] = '/';
}
}
}
else
{
buf[i] = string[i];
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];
}

File diff suppressed because it is too large Load diff

View file

@ -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,19 +337,24 @@ 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;
{
gnustep_local_root = nil;
}
else
RETAIN(gnustep_local_root);
{
RETAIN(gnustep_local_root);
}
}
if (gnustep_local_root == nil)
{
@ -357,19 +385,24 @@ 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;
{
gnustep_network_root = nil;
}
else
RETAIN(gnustep_network_root);
{
RETAIN(gnustep_network_root);
}
}
if (gnustep_network_root == nil)
{
@ -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 = @"/";
root = @"/c/";
#endif
#else
root = @"/";
#endif
}
else
{
root = ImportPath(root, 0);
}
return root;
}