Add "." and ".." processing to expandPath, some better documentation.
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@1819 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -46,9 +46,10 @@ int expandPath (char *dest, size_t len, const char *src, int what);
|
|||||||
#define EP_ENVVARS 4
|
#define EP_ENVVARS 4
|
||||||
// Expand environment variables.
|
// Expand environment variables.
|
||||||
#define EP_DOTS 8
|
#define EP_DOTS 8
|
||||||
// Process '..' and '.' (not implemented)
|
// Process ".." and "."
|
||||||
#define EP_SLASHES 16
|
#define EP_SLASHES 16
|
||||||
// Change (Windows style) backslashes to (Unix style) slashes.
|
// Consider backslashes as path component separators.
|
||||||
|
// They will be replaced by slashes.
|
||||||
#define EP_ALL (EP_HOME | EP_ENVVARS | EP_ABSOLUTE | EP_DOTS | EP_SLASHES)
|
#define EP_ALL (EP_HOME | EP_ENVVARS | EP_ABSOLUTE | EP_DOTS | EP_SLASHES)
|
||||||
// Everything
|
// Everything
|
||||||
// Everything except Windows style backslashes on Unix Systems:
|
// Everything except Windows style backslashes on Unix Systems:
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
|
|
||||||
static char *expandPathAbsolute (char *dest, size_t destLen,
|
static char *expandPathAbsolute (char *dest, size_t destLen,
|
||||||
const char *src, int what);
|
const char *src, int what);
|
||||||
|
static char *strrchr2(const char *start, int c, const char *end);
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -183,8 +184,19 @@ getHomeDir (void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expand ~/ in a path, and replaces \ by / on Windows.
|
// Performs various types of string expansions on a path.
|
||||||
// Environment variable parsing could be added here if we need it.
|
// 'what' is an OR'd compination of the folowing flags, which
|
||||||
|
// specify what type of exmansions will be performed.
|
||||||
|
// EP_HOME - Expand '~' for home dirs.
|
||||||
|
// EP_ABSOLUTE - Make relative paths absolute
|
||||||
|
// EP_ENVVARS - Expand environment variables
|
||||||
|
// EP_DOTS - Process ".." and "."
|
||||||
|
// EP_SLASHES - Consider backslashes as path component separators.
|
||||||
|
// They will be replaced by slashes.
|
||||||
|
// Additionally, there's EP_ALL, which indicates all of the above,
|
||||||
|
// and EP_SYSTEM_ALL, which does the same as EP_ALL, with the exception
|
||||||
|
// of EP_SLASHES, which will only be included if the operating system
|
||||||
|
// accepts backslashes as path terminators.
|
||||||
// Returns 0 on success.
|
// Returns 0 on success.
|
||||||
// Returns -1 on failure, setting errno.
|
// Returns -1 on failure, setting errno.
|
||||||
int
|
int
|
||||||
@@ -360,7 +372,6 @@ expandPath (char *dest, size_t len, const char *src, int what)
|
|||||||
else
|
else
|
||||||
srcend = src + strlen (src);
|
srcend = src + strlen (src);
|
||||||
|
|
||||||
|
|
||||||
if (what & EP_HOME)
|
if (what & EP_HOME)
|
||||||
{
|
{
|
||||||
if (src[0] == '~')
|
if (src[0] == '~')
|
||||||
@@ -429,6 +440,77 @@ expandPath (char *dest, size_t len, const char *src, int what)
|
|||||||
destptr++;
|
destptr++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (what & EP_DOTS) {
|
||||||
|
// At this point backslashes are already replaced by slashes if they
|
||||||
|
// are specified to be path seperators.
|
||||||
|
// Note that the path can only get smaller, so no size checks
|
||||||
|
// need to be done.
|
||||||
|
char *pathStart;
|
||||||
|
// Start of the first path component, after any
|
||||||
|
// leading slashes or drive letters.
|
||||||
|
char *startPart;
|
||||||
|
char *endPart;
|
||||||
|
|
||||||
|
pathStart = dest;
|
||||||
|
#ifdef WIN32
|
||||||
|
if (isDriveLetter(src[0]) && (src[1] == ':'))
|
||||||
|
pathStart += 2;
|
||||||
|
#endif
|
||||||
|
if (pathStart[0] == '/')
|
||||||
|
pathStart++;
|
||||||
|
|
||||||
|
startPart = pathStart;
|
||||||
|
destptr = pathStart;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
endPart = strchr(startPart, '/');
|
||||||
|
if (endPart == NULL)
|
||||||
|
endPart = startPart + strlen(startPart);
|
||||||
|
|
||||||
|
if (endPart - startPart == 1 && startPart[0] == '.')
|
||||||
|
{
|
||||||
|
// Found "." as path component. Ignore this component.
|
||||||
|
}
|
||||||
|
else if (endPart - startPart == 2 &&
|
||||||
|
startPart[0] == '.' && startPart[1] == '.')
|
||||||
|
{
|
||||||
|
// Found ".." as path component. Remove the previous
|
||||||
|
// component, and ignore this one.
|
||||||
|
char *lastSlash;
|
||||||
|
lastSlash = strrchr2(pathStart, '/', destptr - 1);
|
||||||
|
if (lastSlash == NULL)
|
||||||
|
{
|
||||||
|
if (destptr == pathStart)
|
||||||
|
{
|
||||||
|
// We ran out of path components to back out of.
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
destptr = pathStart;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
destptr = lastSlash;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// A normal path component; copy it.
|
||||||
|
// Using memmove as source and destination may overlap.
|
||||||
|
memmove(destptr, startPart, endPart - startPart);
|
||||||
|
destptr += (endPart - startPart);
|
||||||
|
if (*endPart == '/')
|
||||||
|
{
|
||||||
|
*destptr = '/';
|
||||||
|
destptr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*endPart == '\0')
|
||||||
|
break;
|
||||||
|
startPart = endPart + 1;
|
||||||
|
}
|
||||||
|
*destptr = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -476,4 +558,16 @@ expandPathAbsolute (char *dest, size_t destLen, const char *src, int what)
|
|||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// As strrchr, but starts searching from the indicated end of the string.
|
||||||
|
static char *
|
||||||
|
strrchr2(const char *start, int c, const char *end) {
|
||||||
|
for (;;) {
|
||||||
|
end--;
|
||||||
|
if (end < start)
|
||||||
|
return (char *) NULL;
|
||||||
|
if (*end == c)
|
||||||
|
return (char *) end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user