core :: Text :: simplify_path
.
, removing //
, and resolving ..
..
are not resolved if they start the path.
is simplified unless the path is empty/
is not removed/
is removedNote that the method only work on the string:
assert "some/./complex/../../path/from/../to/a////file//".simplify_path == "path/to/a/file"
assert "../dir/file".simplify_path == "../dir/file"
assert "dir/../../".simplify_path == ".."
assert "dir/..".simplify_path == "."
assert "//absolute//path/".simplify_path == "/absolute/path"
assert "//absolute//../".simplify_path == "/"
assert "/".simplify_path == "/"
assert "../".simplify_path == ".."
assert "./".simplify_path == "."
assert "././././././".simplify_path == "."
assert "./../dir".simplify_path == "../dir"
assert "./dir".simplify_path == "dir"
On Windows, '' are replaced by '/':
assert "C:\\some\\.\\complex\\../../path/to/a_file.ext".simplify_path == "C:/path/to/a_file.ext"
assert "C:\\".simplify_path == "C:"
# Simplify a file path by remove useless `.`, removing `//`, and resolving `..`
#
# * `..` are not resolved if they start the path
# * starting `.` is simplified unless the path is empty
# * starting `/` is not removed
# * trailing `/` is removed
#
# Note that the method only work on the string:
#
# * no I/O access is performed
# * the validity of the path is not checked
#
# ~~~
# assert "some/./complex/../../path/from/../to/a////file//".simplify_path == "path/to/a/file"
# assert "../dir/file".simplify_path == "../dir/file"
# assert "dir/../../".simplify_path == ".."
# assert "dir/..".simplify_path == "."
# assert "//absolute//path/".simplify_path == "/absolute/path"
# assert "//absolute//../".simplify_path == "/"
# assert "/".simplify_path == "/"
# assert "../".simplify_path == ".."
# assert "./".simplify_path == "."
# assert "././././././".simplify_path == "."
# assert "./../dir".simplify_path == "../dir"
# assert "./dir".simplify_path == "dir"
# ~~~
#
# On Windows, '\' are replaced by '/':
#
# ~~~nitish
# assert "C:\\some\\.\\complex\\../../path/to/a_file.ext".simplify_path == "C:/path/to/a_file.ext"
# assert "C:\\".simplify_path == "C:"
# ~~~
fun simplify_path: String
do
var s = self
if is_windows then s = s.replace("\\", "/")
var a = s.split_with("/")
var a2 = new Array[String]
for x in a do
if x == "." and not a2.is_empty then continue # skip `././`
if x == "" and not a2.is_empty then continue # skip `//`
if x == ".." and not a2.is_empty and a2.last != ".." then
if a2.last == "." then # do not skip `./../`
a2.pop # reduce `./../` in `../`
else # reduce `dir/../` in `/`
a2.pop
continue
end
else if not a2.is_empty and a2.last == "." then
a2.pop # reduce `./dir` in `dir`
end
a2.push(x)
end
if a2.is_empty then return "."
if a2.length == 1 and a2.first == "" then return "/"
return a2.join("/")
end
lib/core/file.nit:1040,2--1097,4