expandFilename on windows is now consistent with other platforms (#10154)

This commit is contained in:
Neelesh Chandola 2019-01-04 19:41:48 +05:30 • committed by Andreas Rumpf
commit e9a192c36f
2 changed files with 49 additions and 52 deletions

View file

@ -482,15 +482,6 @@ proc setDefaultLibpath*(conf: ConfigRef) =
conf.libpath = AbsoluteDir parentNimLibPath conf.libpath = AbsoluteDir parentNimLibPath
proc canonicalizePath*(conf: ConfigRef; path: AbsoluteFile): AbsoluteFile = proc canonicalizePath*(conf: ConfigRef; path: AbsoluteFile): AbsoluteFile =
# on Windows, 'expandFilename' calls getFullPathName which doesn't do
# case corrections, so we have to use this convoluted way of retrieving
# the true filename (see tests/modules and Nimble uses 'import Uri' instead
# of 'import uri'):
when defined(windows):
result = AbsoluteFile path.string.expandFilename
for x in walkFiles(result.string):
return AbsoluteFile x
else:
result = AbsoluteFile path.string.expandFilename result = AbsoluteFile path.string.expandFilename
proc shortenDir*(conf: ConfigRef; dir: string): string {. proc shortenDir*(conf: ConfigRef; dir: string): string {.

View file

@ -945,48 +945,6 @@ when not weirdTarget:
raise newException(ValueError, "The specified root is not absolute: " & root) raise newException(ValueError, "The specified root is not absolute: " & root)
joinPath(root, path) joinPath(root, path)
proc expandFilename*(filename: string): string {.rtl, extern: "nos$1",
tags: [ReadDirEffect], noNimScript.} =
## Returns the full (`absolute`:idx:) path of an existing file `filename`,
## raises OSError in case of an error. Follows symlinks.
when defined(windows):
var bufsize = MAX_PATH.int32
when useWinUnicode:
var unused: WideCString = nil
var res = newWideCString("", bufsize)
while true:
var L = getFullPathNameW(newWideCString(filename), bufsize, res, unused)
if L == 0'i32:
raiseOSError(osLastError())
elif L > bufsize:
res = newWideCString("", L)
bufsize = L
else:
result = res$L
break
else:
var unused: cstring = nil
result = newString(bufsize)
while true:
var L = getFullPathNameA(filename, bufsize, result, unused)
if L == 0'i32:
raiseOSError(osLastError())
elif L > bufsize:
result = newString(L)
bufsize = L
else:
setLen(result, L)
break
else:
# according to Posix we don't need to allocate space for result pathname.
# But we need to free return value with free(3).
var r = realpath(filename, nil)
if r.isNil:
raiseOSError(osLastError())
else:
result = $r
c_free(cast[pointer](r))
proc normalizePath*(path: var string) {.rtl, extern: "nos$1", tags: [], noNimScript.} = proc normalizePath*(path: var string) {.rtl, extern: "nos$1", tags: [], noNimScript.} =
## Normalize a path. ## Normalize a path.
## ##
@ -1425,6 +1383,54 @@ iterator walkDirs*(pattern: string): string {.tags: [ReadDirEffect], noNimScript
## notation is supported. ## notation is supported.
walkCommon(pattern, isDir) walkCommon(pattern, isDir)
proc expandFilename*(filename: string): string {.rtl, extern: "nos$1",
tags: [ReadDirEffect], noNimScript.} =
## Returns the full (`absolute`:idx:) path of an existing file `filename`,
## raises OSError in case of an error. Follows symlinks.
when defined(windows):
var bufsize = MAX_PATH.int32
when useWinUnicode:
var unused: WideCString = nil
var res = newWideCString("", bufsize)
while true:
var L = getFullPathNameW(newWideCString(filename), bufsize, res, unused)
if L == 0'i32:
raiseOSError(osLastError())
elif L > bufsize:
res = newWideCString("", L)
bufsize = L
else:
result = res$L
break
else:
var unused: cstring = nil
result = newString(bufsize)
while true:
var L = getFullPathNameA(filename, bufsize, result, unused)
if L == 0'i32:
raiseOSError(osLastError())
elif L > bufsize:
result = newString(L)
bufsize = L
else:
setLen(result, L)
break
# getFullPathName doesn't do case corrections, so we have to use this convoluted
# way of retrieving the true filename
for x in walkFiles(result.string):
result = x
if not existsFile(result) and not existsDir(result):
raise newException(OSError, "file does not exist")
else:
# according to Posix we don't need to allocate space for result pathname.
# But we need to free return value with free(3).
var r = realpath(filename, nil)
if r.isNil:
raiseOSError(osLastError())
else:
result = $r
c_free(cast[pointer](r))
type type
PathComponent* = enum ## Enumeration specifying a path component. PathComponent* = enum ## Enumeration specifying a path component.
pcFile, ## path refers to a file pcFile, ## path refers to a file