diff options
Diffstat (limited to 'lib/std/private/ospaths2.nim')
-rw-r--r-- | lib/std/private/ospaths2.nim | 82 |
1 files changed, 42 insertions, 40 deletions
diff --git a/lib/std/private/ospaths2.nim b/lib/std/private/ospaths2.nim index 75c34ecf5..bc69ff725 100644 --- a/lib/std/private/ospaths2.nim +++ b/lib/std/private/ospaths2.nim @@ -1,7 +1,7 @@ include system/inclrtl import std/private/since -import strutils, pathnorm +import std/[strutils, pathnorm] import std/oserrors import oscommon @@ -10,14 +10,16 @@ export ReadDirEffect, WriteDirEffect when defined(nimPreviewSlimSystem): import std/[syncio, assertions, widestrs] +## .. importdoc:: osappdirs.nim, osdirs.nim, osseps.nim, os.nim + const weirdTarget = defined(nimscript) or defined(js) when weirdTarget: discard elif defined(windows): - import winlean + import std/winlean elif defined(posix): - import posix, system/ansi_c + import std/posix, system/ansi_c else: {.error: "OS module not ported to your operating system!".} @@ -252,12 +254,12 @@ proc isAbsolute*(path: string): bool {.rtl, noSideEffect, extern: "nos$1", raise result = path[0] != ':' elif defined(RISCOS): result = path[0] == '$' - elif defined(posix) or defined(js): - # `or defined(js)` wouldn't be needed pending https://github.com/nim-lang/Nim/issues/13469 - # This works around the problem for posix, but Windows is still broken with nim js -d:nodejs + elif defined(posix): result = path[0] == '/' + elif defined(nodejs): + {.emit: [result," = require(\"path\").isAbsolute(",path.cstring,");"].} else: - doAssert false # if ever hits here, adapt as needed + raiseAssert "unreachable" # if ever hits here, adapt as needed when FileSystemCaseSensitive: template `!=?`(a, b: char): bool = a != b @@ -569,7 +571,7 @@ proc normExt(ext: string): string = proc searchExtPos*(path: string): int = ## Returns index of the `'.'` char in `path` if it signifies the beginning - ## of extension. Returns -1 otherwise. + ## of the file extension. Returns -1 otherwise. ## ## See also: ## * `splitFile proc`_ @@ -582,15 +584,28 @@ proc searchExtPos*(path: string): int = assert searchExtPos("c.nim") == 1 assert searchExtPos("a/b/c.nim") == 5 assert searchExtPos("a.b.c.nim") == 5 + assert searchExtPos(".nim") == -1 + assert searchExtPos("..nim") == -1 + assert searchExtPos("a..nim") == 2 - # BUGFIX: do not search until 0! .DS_Store is no file extension! + # Unless there is any char that is not `ExtSep` before last `ExtSep` in the file name, + # it is not a file extension. + const DirSeps = when doslikeFileSystem: {DirSep, AltSep, ':'} else: {DirSep, AltSep} result = -1 - for i in countdown(len(path)-1, 1): + var i = path.high + while i >= 1: if path[i] == ExtSep: + break + elif path[i] in DirSeps: + return -1 # do not skip over path + dec i + + for j in countdown(i - 1, 0): + if path[j] in DirSeps: + return -1 + elif path[j] != ExtSep: result = i break - elif path[i] in {DirSep, AltSep}: - break # do not skip over path proc splitFile*(path: string): tuple[dir, name, ext: string] {. noSideEffect, rtl, extern: "nos$1".} = @@ -748,9 +763,9 @@ proc cmpPaths*(pathA, pathB: string): int {. ## On a case-sensitive filesystem this is done ## case-sensitively otherwise case-insensitively. Returns: ## - ## | 0 if pathA == pathB - ## | < 0 if pathA < pathB - ## | > 0 if pathA > pathB + ## | `0` if pathA == pathB + ## | `< 0` if pathA < pathB + ## | `> 0` if pathA > pathB runnableExamples: when defined(macosx): assert cmpPaths("foo", "Foo") == 0 @@ -844,33 +859,20 @@ when not defined(nimscript): {.emit: "`ret` = process.cwd();".} return $ret elif defined(js): - doAssert false, "use -d:nodejs to have `getCurrentDir` defined" + raiseAssert "use -d:nodejs to have `getCurrentDir` defined" elif defined(windows): var bufsize = MAX_PATH.int32 - when useWinUnicode: - var res = newWideCString("", bufsize) - while true: - var L = getCurrentDirectoryW(bufsize, res) - if L == 0'i32: - raiseOSError(osLastError()) - elif L > bufsize: - res = newWideCString("", L) - bufsize = L - else: - result = res$L - break - else: - result = newString(bufsize) - while true: - var L = getCurrentDirectoryA(bufsize, result) - if L == 0'i32: - raiseOSError(osLastError()) - elif L > bufsize: - result = newString(L) - bufsize = L - else: - setLen(result, L) - break + var res = newWideCString(bufsize) + while true: + var L = getCurrentDirectoryW(bufsize, res) + if L == 0'i32: + raiseOSError(osLastError()) + elif L > bufsize: + res = newWideCString(L) + bufsize = L + else: + result = res$L + break else: var bufsize = 1024 # should be enough result = newString(bufsize) |