mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 05:50:30 +00:00
committed by
Andreas Rumpf
parent
b97a7dbf3d
commit
a98b1a7764
@@ -157,6 +157,29 @@ const
|
||||
## The character which separates the base filename from the extension;
|
||||
## for example, the '.' in ``os.nim``.
|
||||
|
||||
proc normalizePathEnd(path: var string, trailingSep = false) =
|
||||
## ensures ``path`` has exactly 0 or 1 trailing `DirSep`, depending on
|
||||
## ``trailingSep``, and taking care of edge cases: it preservers whether
|
||||
## a path is absolute or relative, and makes sure trailing sep is `DirSep`,
|
||||
## not `AltSep`.
|
||||
if path.len == 0: return
|
||||
var i = path.len
|
||||
while i >= 1 and path[i-1] in {DirSep, AltSep}: dec(i)
|
||||
if trailingSep:
|
||||
# foo// => foo
|
||||
path.setLen(i)
|
||||
# foo => foo/
|
||||
path.add DirSep
|
||||
elif i>0:
|
||||
# foo// => foo
|
||||
path.setLen(i)
|
||||
else:
|
||||
# // => / (empty case was already taken care of)
|
||||
path = $DirSep
|
||||
|
||||
proc normalizePathEnd(path: string, trailingSep = false): string =
|
||||
result = path
|
||||
result.normalizePathEnd(trailingSep)
|
||||
|
||||
proc joinPath*(head, tail: string): string {.
|
||||
noSideEffect, rtl, extern: "nos$1".} =
|
||||
@@ -253,10 +276,15 @@ proc parentDir*(path: string): string {.
|
||||
noSideEffect, rtl, extern: "nos$1".} =
|
||||
## Returns the parent directory of `path`.
|
||||
##
|
||||
## This is often the same as the ``head`` result of ``splitPath``.
|
||||
## If there is no parent, "" is returned.
|
||||
## | Example: ``parentDir("/usr/local/bin") == "/usr/local"``.
|
||||
## | Example: ``parentDir("/usr/local/bin/") == "/usr/local"``.
|
||||
## This is the same as ``splitPath(path).head`` when ``path`` doesn't end
|
||||
## in a dir separator.
|
||||
## The remainder can be obtained with ``lastPathPart(path)``
|
||||
runnableExamples:
|
||||
doAssert parentDir("") == ""
|
||||
when defined(posix):
|
||||
doAssert parentDir("/usr/local/bin") == "/usr/local"
|
||||
doAssert parentDir("foo/bar/") == "foo"
|
||||
|
||||
let sepPos = parentDirPos(path)
|
||||
if sepPos >= 0:
|
||||
result = substr(path, 0, sepPos-1)
|
||||
@@ -368,12 +396,25 @@ proc splitFile*(path: string): tuple[dir, name, ext: string] {.
|
||||
proc extractFilename*(path: string): string {.
|
||||
noSideEffect, rtl, extern: "nos$1".} =
|
||||
## Extracts the filename of a given `path`. This is the same as
|
||||
## ``name & ext`` from ``splitFile(path)``.
|
||||
## ``name & ext`` from ``splitFile(path)``. See also ``lastPathPart``.
|
||||
runnableExamples:
|
||||
when defined(posix):
|
||||
doAssert extractFilename("foo/bar/") == ""
|
||||
doAssert extractFilename("foo/bar") == "bar"
|
||||
if path.len == 0 or path[path.len-1] in {DirSep, AltSep}:
|
||||
result = ""
|
||||
else:
|
||||
result = splitPath(path).tail
|
||||
|
||||
proc lastPathPart*(path: string): string {.
|
||||
noSideEffect, rtl, extern: "nos$1".} =
|
||||
## like ``extractFilename``, but ignores trailing dir separator; aka: baseName
|
||||
## in some other languages.
|
||||
runnableExamples:
|
||||
when defined(posix):
|
||||
doAssert lastPathPart("foo/bar/") == "bar"
|
||||
let path = path.normalizePathEnd(trailingSep = false)
|
||||
result = extractFilename(path)
|
||||
|
||||
proc changeFileExt*(filename, ext: string): string {.
|
||||
noSideEffect, rtl, extern: "nos$1".} =
|
||||
@@ -449,31 +490,6 @@ proc isAbsolute*(path: string): bool {.rtl, noSideEffect, extern: "nos$1".} =
|
||||
elif defined(posix):
|
||||
result = path[0] == '/'
|
||||
|
||||
|
||||
proc normalizePathEnd(path: var string, trailingSep = false) =
|
||||
## ensures ``path`` has exactly 0 or 1 trailing `DirSep`, depending on
|
||||
## ``trailingSep``, and taking care of edge cases: it preservers whether
|
||||
## a path is absolute or relative, and makes sure trailing sep is `DirSep`,
|
||||
## not `AltSep`.
|
||||
if path.len == 0: return
|
||||
var i = path.len
|
||||
while i >= 1 and path[i-1] in {DirSep, AltSep}: dec(i)
|
||||
if trailingSep:
|
||||
# foo// => foo
|
||||
path.setLen(i)
|
||||
# foo => foo/
|
||||
path.add DirSep
|
||||
elif i>0:
|
||||
# foo// => foo
|
||||
path.setLen(i)
|
||||
else:
|
||||
# // => / (empty case was already taken care of)
|
||||
path = $DirSep
|
||||
|
||||
proc normalizePathEnd(path: string, trailingSep = false): string =
|
||||
result = path
|
||||
result.normalizePathEnd(trailingSep)
|
||||
|
||||
proc unixToNativePath*(path: string, drive=""): string {.
|
||||
noSideEffect, rtl, extern: "nos$1".} =
|
||||
## Converts an UNIX-like path to a native one.
|
||||
|
||||
@@ -18,24 +18,47 @@ doAssert isAbsolute(unixToNativePath("/a/b", "a"))
|
||||
doAssert unixToNativePath("a/b") == joinPath("a", "b")
|
||||
|
||||
when defined(macos):
|
||||
doAssert unixToNativePath("./") == ":"
|
||||
doAssert unixToNativePath("./abc") == ":abc"
|
||||
doAssert unixToNativePath("../abc") == "::abc"
|
||||
doAssert unixToNativePath("../../abc") == ":::abc"
|
||||
doAssert unixToNativePath("/abc", "a") == "abc"
|
||||
doAssert unixToNativePath("/abc/def", "a") == "abc:def"
|
||||
doAssert unixToNativePath("./") == ":"
|
||||
doAssert unixToNativePath("./abc") == ":abc"
|
||||
doAssert unixToNativePath("../abc") == "::abc"
|
||||
doAssert unixToNativePath("../../abc") == ":::abc"
|
||||
doAssert unixToNativePath("/abc", "a") == "abc"
|
||||
doAssert unixToNativePath("/abc/def", "a") == "abc:def"
|
||||
elif doslikeFileSystem:
|
||||
doAssert unixToNativePath("./") == ".\\"
|
||||
doAssert unixToNativePath("./abc") == ".\\abc"
|
||||
doAssert unixToNativePath("../abc") == "..\\abc"
|
||||
doAssert unixToNativePath("../../abc") == "..\\..\\abc"
|
||||
doAssert unixToNativePath("/abc", "a") == "a:\\abc"
|
||||
doAssert unixToNativePath("/abc/def", "a") == "a:\\abc\\def"
|
||||
doAssert unixToNativePath("./") == ".\\"
|
||||
doAssert unixToNativePath("./abc") == ".\\abc"
|
||||
doAssert unixToNativePath("../abc") == "..\\abc"
|
||||
doAssert unixToNativePath("../../abc") == "..\\..\\abc"
|
||||
doAssert unixToNativePath("/abc", "a") == "a:\\abc"
|
||||
doAssert unixToNativePath("/abc/def", "a") == "a:\\abc\\def"
|
||||
else:
|
||||
#Tests for unix
|
||||
doAssert unixToNativePath("./") == "./"
|
||||
doAssert unixToNativePath("./abc") == "./abc"
|
||||
doAssert unixToNativePath("../abc") == "../abc"
|
||||
doAssert unixToNativePath("../../abc") == "../../abc"
|
||||
doAssert unixToNativePath("/abc", "a") == "/abc"
|
||||
doAssert unixToNativePath("/abc/def", "a") == "/abc/def"
|
||||
#Tests for unix
|
||||
doAssert unixToNativePath("./") == "./"
|
||||
doAssert unixToNativePath("./abc") == "./abc"
|
||||
doAssert unixToNativePath("../abc") == "../abc"
|
||||
doAssert unixToNativePath("../../abc") == "../../abc"
|
||||
doAssert unixToNativePath("/abc", "a") == "/abc"
|
||||
doAssert unixToNativePath("/abc/def", "a") == "/abc/def"
|
||||
|
||||
block extractFilenameTest:
|
||||
doAssert extractFilename("") == ""
|
||||
when defined(posix):
|
||||
doAssert extractFilename("foo/bar") == "bar"
|
||||
doAssert extractFilename("foo/bar.txt") == "bar.txt"
|
||||
doAssert extractFilename("foo/") == ""
|
||||
doAssert extractFilename("/") == ""
|
||||
when doslikeFileSystem:
|
||||
doAssert extractFilename(r"foo\bar") == "bar"
|
||||
doAssert extractFilename(r"foo\bar.txt") == "bar.txt"
|
||||
doAssert extractFilename(r"foo\") == ""
|
||||
doAssert extractFilename(r"C:\") == ""
|
||||
|
||||
block lastPathPartTest:
|
||||
doAssert lastPathPart("") == ""
|
||||
when defined(posix):
|
||||
doAssert lastPathPart("foo/bar.txt") == "bar.txt"
|
||||
doAssert lastPathPart("foo/") == "foo"
|
||||
doAssert lastPathPart("/") == ""
|
||||
when doslikeFileSystem:
|
||||
doAssert lastPathPart(r"foo\bar.txt") == "bar.txt"
|
||||
doAssert lastPathPart(r"foo\") == "foo"
|
||||
|
||||
Reference in New Issue
Block a user