* fix #13455 ; joinPath(a,b) now honors trailing slashes in b (or a if b = "") * fix test windows
This commit is contained in:
parent
11db28bc61
commit
0c312ad898
3 changed files with 47 additions and 17 deletions
|
|
@ -29,7 +29,8 @@
|
||||||
are converted to `None`.
|
are converted to `None`.
|
||||||
- `relativePath("foo", "foo")` is now `"."`, not `""`, as `""` means invalid path
|
- `relativePath("foo", "foo")` is now `"."`, not `""`, as `""` means invalid path
|
||||||
and shouldn't be conflated with `"."`; use -d:nimOldRelativePathBehavior to restore the old
|
and shouldn't be conflated with `"."`; use -d:nimOldRelativePathBehavior to restore the old
|
||||||
behavioe
|
behavior
|
||||||
|
- `joinPath(a,b)` now honors trailing slashes in `b` (or `a` if `b` = "")
|
||||||
|
|
||||||
### Breaking changes in the compiler
|
### Breaking changes in the compiler
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -122,14 +122,21 @@ proc normalizePathEnd(path: string, trailingSep = false): string =
|
||||||
since((1, 1)):
|
since((1, 1)):
|
||||||
export normalizePathEnd
|
export normalizePathEnd
|
||||||
|
|
||||||
|
template endsWith(a: string, b: set[char]): bool =
|
||||||
|
a.len > 0 and a[^1] in b
|
||||||
|
|
||||||
|
proc joinPathImpl(result: var string, state: var int, tail: string) =
|
||||||
|
let trailingSep = tail.endsWith({DirSep, AltSep}) or tail.len == 0 and result.endsWith({DirSep, AltSep})
|
||||||
|
addNormalizePath(tail, result, state, DirSep)
|
||||||
|
normalizePathEnd(result, trailingSep=trailingSep)
|
||||||
|
|
||||||
proc joinPath*(head, tail: string): string {.
|
proc joinPath*(head, tail: string): string {.
|
||||||
noSideEffect, rtl, extern: "nos$1".} =
|
noSideEffect, rtl, extern: "nos$1".} =
|
||||||
## Joins two directory names to one.
|
## Joins two directory names to one.
|
||||||
##
|
##
|
||||||
## If `head` is the empty string, `tail` is returned. If `tail` is the empty
|
## returns normalized path concatenation of `head` and `tail`, preserving
|
||||||
## string, `head` is returned with a trailing path separator. If `tail` starts
|
## whether or not `tail` has a trailing slash (or, if tail if empty, whether
|
||||||
## with a path separator it will be removed when concatenated to `head`.
|
## head has one).
|
||||||
## Path separators will be normalized.
|
|
||||||
##
|
##
|
||||||
## See also:
|
## See also:
|
||||||
## * `joinPath(varargs) proc <#joinPath,varargs[string]>`_
|
## * `joinPath(varargs) proc <#joinPath,varargs[string]>`_
|
||||||
|
|
@ -140,7 +147,9 @@ proc joinPath*(head, tail: string): string {.
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
when defined(posix):
|
when defined(posix):
|
||||||
assert joinPath("usr", "lib") == "usr/lib"
|
assert joinPath("usr", "lib") == "usr/lib"
|
||||||
assert joinPath("usr", "") == "usr/"
|
assert joinPath("usr", "lib/") == "usr/lib/"
|
||||||
|
assert joinPath("usr", "") == "usr"
|
||||||
|
assert joinPath("usr/", "") == "usr/"
|
||||||
assert joinPath("", "") == ""
|
assert joinPath("", "") == ""
|
||||||
assert joinPath("", "lib") == "lib"
|
assert joinPath("", "lib") == "lib"
|
||||||
assert joinPath("", "/lib") == "/lib"
|
assert joinPath("", "/lib") == "/lib"
|
||||||
|
|
@ -149,11 +158,8 @@ proc joinPath*(head, tail: string): string {.
|
||||||
|
|
||||||
result = newStringOfCap(head.len + tail.len)
|
result = newStringOfCap(head.len + tail.len)
|
||||||
var state = 0
|
var state = 0
|
||||||
addNormalizePath(head, result, state, DirSep)
|
joinPathImpl(result, state, head)
|
||||||
if result.len != 0 and result[^1] notin {DirSep, AltSep} and tail.len == 0:
|
joinPathImpl(result, state, tail)
|
||||||
result.add DirSep
|
|
||||||
else:
|
|
||||||
addNormalizePath(tail, result, state, DirSep)
|
|
||||||
when false:
|
when false:
|
||||||
if len(head) == 0:
|
if len(head) == 0:
|
||||||
result = tail
|
result = tail
|
||||||
|
|
@ -192,7 +198,7 @@ proc joinPath*(parts: varargs[string]): string {.noSideEffect,
|
||||||
result = newStringOfCap(estimatedLen)
|
result = newStringOfCap(estimatedLen)
|
||||||
var state = 0
|
var state = 0
|
||||||
for i in 0..high(parts):
|
for i in 0..high(parts):
|
||||||
addNormalizePath(parts[i], result, state, DirSep)
|
joinPathImpl(result, state, parts[i])
|
||||||
|
|
||||||
proc `/`*(head, tail: string): string {.noSideEffect.} =
|
proc `/`*(head, tail: string): string {.noSideEffect.} =
|
||||||
## The same as `joinPath(head, tail) proc <#joinPath,string,string>`_.
|
## The same as `joinPath(head, tail) proc <#joinPath,string,string>`_.
|
||||||
|
|
@ -206,10 +212,10 @@ proc `/`*(head, tail: string): string {.noSideEffect.} =
|
||||||
## * `uri./ proc <uri.html#/,Uri,string>`_
|
## * `uri./ proc <uri.html#/,Uri,string>`_
|
||||||
runnableExamples:
|
runnableExamples:
|
||||||
when defined(posix):
|
when defined(posix):
|
||||||
assert "usr" / "" == "usr/"
|
assert "usr" / "" == "usr"
|
||||||
assert "" / "lib" == "lib"
|
assert "" / "lib" == "lib"
|
||||||
assert "" / "/lib" == "/lib"
|
assert "" / "/lib" == "/lib"
|
||||||
assert "usr/" / "/lib" == "usr/lib"
|
assert "usr/" / "/lib/" == "usr/lib/"
|
||||||
assert "usr" / "lib" / "../bin" == "usr/bin"
|
assert "usr" / "lib" / "../bin" == "usr/bin"
|
||||||
|
|
||||||
return joinPath(head, tail)
|
return joinPath(head, tail)
|
||||||
|
|
|
||||||
|
|
@ -357,14 +357,37 @@ block ospaths:
|
||||||
doAssert relativePath(r"\\foo\bar\baz.nim", r"\foo") == r"\\foo\bar\baz.nim"
|
doAssert relativePath(r"\\foo\bar\baz.nim", r"\foo") == r"\\foo\bar\baz.nim"
|
||||||
doAssert relativePath(r"c:\foo.nim", r"\foo") == r"c:\foo.nim"
|
doAssert relativePath(r"c:\foo.nim", r"\foo") == r"c:\foo.nim"
|
||||||
|
|
||||||
doAssert joinPath("usr", "") == unixToNativePath"usr/"
|
doAssert joinPath("usr", "") == unixToNativePath"usr"
|
||||||
doAssert joinPath("", "lib") == "lib"
|
doAssert joinPath("", "lib") == "lib"
|
||||||
doAssert joinPath("", "/lib") == unixToNativePath"/lib"
|
doAssert joinPath("", "/lib") == unixToNativePath"/lib"
|
||||||
doAssert joinPath("usr/", "/lib") == unixToNativePath"usr/lib"
|
doAssert joinPath("usr/", "/lib") == unixToNativePath"usr/lib"
|
||||||
doAssert joinPath("", "") == unixToNativePath""
|
doAssert joinPath("", "") == unixToNativePath"" # issue #13455
|
||||||
doAssert joinPath("/" / "") == unixToNativePath"/"
|
doAssert joinPath("", "/") == unixToNativePath"/"
|
||||||
|
doAssert joinPath("/", "/") == unixToNativePath"/"
|
||||||
|
doAssert joinPath("/", "") == unixToNativePath"/"
|
||||||
|
doAssert joinPath("/" / "") == unixToNativePath"/" # weird test case...
|
||||||
doAssert joinPath("/", "/a/b/c") == unixToNativePath"/a/b/c"
|
doAssert joinPath("/", "/a/b/c") == unixToNativePath"/a/b/c"
|
||||||
doAssert joinPath("foo/","") == unixToNativePath"foo/"
|
doAssert joinPath("foo/","") == unixToNativePath"foo/"
|
||||||
|
doAssert joinPath("foo/","abc") == unixToNativePath"foo/abc"
|
||||||
|
doAssert joinPath("foo//./","abc/.//") == unixToNativePath"foo/abc/"
|
||||||
|
doAssert joinPath("foo","abc") == unixToNativePath"foo/abc"
|
||||||
|
doAssert joinPath("","abc") == unixToNativePath"abc"
|
||||||
|
|
||||||
|
doAssert joinPath("gook/.","abc") == unixToNativePath"gook/abc"
|
||||||
|
|
||||||
|
# controversial: inconsistent with `joinPath("gook/.","abc")`
|
||||||
|
# on linux, `./foo` and `foo` are treated a bit differently for executables
|
||||||
|
# but not `./foo/bar` and `foo/bar`
|
||||||
|
doAssert joinPath(".", "/lib") == unixToNativePath"./lib"
|
||||||
|
doAssert joinPath(".","abc") == unixToNativePath"./abc"
|
||||||
|
|
||||||
|
# cases related to issue #13455
|
||||||
|
doAssert joinPath("foo", "", "") == "foo"
|
||||||
|
doAssert joinPath("foo", "") == "foo"
|
||||||
|
doAssert joinPath("foo/", "") == unixToNativePath"foo/"
|
||||||
|
doAssert joinPath("foo/", ".") == "foo"
|
||||||
|
doAssert joinPath("foo", "./") == unixToNativePath"foo/"
|
||||||
|
doAssert joinPath("foo", "", "bar/") == unixToNativePath"foo/bar/"
|
||||||
|
|
||||||
block getTempDir:
|
block getTempDir:
|
||||||
block TMPDIR:
|
block TMPDIR:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue