* A path canonicaliser that doesn't depend on the existence of paths
(i.e., it doesn't use realpath(3), which is broken in any case). Therefore it doesn't resolve symlinks.
This commit is contained in:
parent
333f4963de
commit
cab3f4977a
|
@ -71,6 +71,15 @@ void runTests()
|
||||||
abort();
|
abort();
|
||||||
} catch (BadRefError err) { };
|
} catch (BadRefError err) { };
|
||||||
|
|
||||||
|
/* Path canonicalisation. */
|
||||||
|
cout << canonPath("/./../././//") << endl;
|
||||||
|
cout << canonPath("/foo/bar") << endl;
|
||||||
|
cout << canonPath("///foo/////bar//") << endl;
|
||||||
|
cout << canonPath("/././/foo/////bar//.") << endl;
|
||||||
|
cout << canonPath("/foo////bar//..///x/") << endl;
|
||||||
|
cout << canonPath("/foo////bar//..//..//x/y/../z/") << endl;
|
||||||
|
cout << canonPath("/foo/bar/../../../..///") << endl;
|
||||||
|
|
||||||
/* Dumping. */
|
/* Dumping. */
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
38
src/util.cc
38
src/util.cc
|
@ -40,11 +40,39 @@ string absPath(string path, string dir)
|
||||||
|
|
||||||
string canonPath(const string & path)
|
string canonPath(const string & path)
|
||||||
{
|
{
|
||||||
char resolved[PATH_MAX];
|
string s;
|
||||||
if (!realpath(path.c_str(), resolved))
|
|
||||||
throw SysError(format("cannot canonicalise path `%1%'") % path);
|
if (path[0] != '/')
|
||||||
/* !!! check that this removes trailing slashes */
|
throw Error(format("not an absolute path: `%1%'") % path);
|
||||||
return resolved;
|
|
||||||
|
string::const_iterator i = path.begin(), end = path.end();
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
|
||||||
|
/* Skip slashes. */
|
||||||
|
while (i != end && *i == '/') i++;
|
||||||
|
if (i == end) break;
|
||||||
|
|
||||||
|
/* Ignore `.'. */
|
||||||
|
if (*i == '.' && (i + 1 == end || i[1] == '/'))
|
||||||
|
i++;
|
||||||
|
|
||||||
|
/* If `..', delete the last component. */
|
||||||
|
else if (*i == '.' && i + 1 < end && i[1] == '.' &&
|
||||||
|
(i + 2 == end || i[2] == '/'))
|
||||||
|
{
|
||||||
|
if (!s.empty()) s.erase(s.rfind('/'));
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Normal component; copy it. */
|
||||||
|
else {
|
||||||
|
s += '/';
|
||||||
|
while (i != end && *i != '/') s += *i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.empty() ? "/" : s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue