normalize

Normalizes a path component.

  • . segments are removed
  • <segment>/.. are removed

Multiple consecutive forward slashes are replaced with a single forward slash. On Windows, \ will be converted to / prior to any normalization.

Note that any number of .. segments at the front is ignored, unless it is an absolute path, in which case they are removed.

The input path is copied into either the provided buffer, or a heap allocated array if no buffer was provided. Normalization modifies this copy before returning the relevant slice.

normalize("/home/foo/./bar/../../john/doe"); // => "/home/john/doe"

Note: Allocates memory.

mstring
normalize
(
cstring in_path
,
mstring buf = null
)

Examples

test (normalize ("") == "");
test (normalize ("/home/../john/../.tango/.htaccess") == "/.tango/.htaccess");
test (normalize ("/home/../john/../.tango/foo.conf") == "/.tango/foo.conf");
test (normalize ("/home/john/.tango/foo.conf") == "/home/john/.tango/foo.conf");
test (normalize ("/foo/bar/.htaccess") == "/foo/bar/.htaccess");
test (normalize ("foo/bar/././.") == "foo/bar/");
test (normalize ("././foo/././././bar") == "foo/bar");
test (normalize ("/foo/../john") == "/john");
test (normalize ("foo/../john") == "john");
test (normalize ("foo/bar/..") == "foo/");
test (normalize ("foo/bar/../john") == "foo/john");
test (normalize ("foo/bar/doe/../../john") == "foo/john");
test (normalize ("foo/bar/doe/../../john/../bar") == "foo/bar");
test (normalize ("./foo/bar/doe") == "foo/bar/doe");
test (normalize ("./foo/bar/doe/../../john/../bar") == "foo/bar");
test (normalize ("./foo/bar/../../john/../bar") == "bar");
test (normalize ("foo/bar/./doe/../../john") == "foo/john");
test (normalize ("../../foo/bar") == "../../foo/bar");
test (normalize ("../../../foo/bar") == "../../../foo/bar");
test (normalize ("d/") == "d/");
test (normalize ("/home/john/./foo/bar.txt") == "/home/john/foo/bar.txt");
test (normalize ("/home//john") == "/home/john");

test (normalize("/../../bar/") == "/bar/");
test (normalize("/../../bar/../baz/./") == "/baz/");
test (normalize("/../../bar/boo/../baz/.bar/.") == "/bar/baz/.bar/");
test (normalize("../..///.///bar/..//..//baz/.//boo/..") == "../../../baz/");
test (normalize("./bar/./..boo/./..bar././/") == "bar/..boo/..bar./");
test (normalize("/bar/..") == "/");
test (normalize("bar/") == "bar/");
test (normalize(".../") == ".../");
test (normalize("///../foo") == "/foo");
test (normalize("./foo") == "foo");
auto buf = new char[100];
auto ret = normalize("foo/bar/./baz", buf);
test (ret.ptr == buf.ptr);
test (ret == "foo/bar/baz");

Meta