diff options
author | Neelesh Chandola <neelesh.chandola@outlook.com> | 2019-01-04 19:41:48 +0530 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2019-01-04 15:11:48 +0100 |
commit | e9a192c36fb62331db0bbd308433e56fc771c352 (patch) | |
tree | 1a764aa311f5113cf1e9750fb47d9c1491486841 /lib/pure | |
parent | ba7d33b4e46f9eafb4980f7a2b4865c5914e0fcc (diff) | |
download | Nim-e9a192c36fb62331db0bbd308433e56fc771c352.tar.gz |
expandFilename on windows is now consistent with other platforms (#10154)
Diffstat (limited to 'lib/pure')
-rw-r--r-- | lib/pure/os.nim | 90 |
1 files changed, 48 insertions, 42 deletions
diff --git a/lib/pure/os.nim b/lib/pure/os.nim index b6cef191b..ab87101c2 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -945,48 +945,6 @@ when not weirdTarget: raise newException(ValueError, "The specified root is not absolute: " & root) 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.} = ## Normalize a path. ## @@ -1425,6 +1383,54 @@ iterator walkDirs*(pattern: string): string {.tags: [ReadDirEffect], noNimScript ## notation is supported. 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 PathComponent* = enum ## Enumeration specifying a path component. pcFile, ## path refers to a file |