Skip to content

Commit 4d46d9b

Browse files
committed
added os.nativeToUnixPath, os.absolutePrefix
1 parent 706de1a commit 4d46d9b

File tree

2 files changed

+47
-1
lines changed

2 files changed

+47
-1
lines changed

changelog.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
(see #13222); instead they now use `getCurrentDir` to resolve those cases,
3737
and this can now throw in edge cases where `getCurrentDir` throws.
3838
`relativePath` also now works for js with `-d:nodejs`.
39-
39+
- Added `os.absolutePrefix` to return the root path component for absolute paths
40+
- Added `os.nativeToUnixPath` to convert a native path to a UNIX path.
4041

4142
## Language changes
4243
- In newruntime it is now allowed to assign discriminator field without restrictions as long as case object doesn't have custom destructor. Discriminator value doesn't have to be a constant either. If you have custom destructor for case object and you do want to freely assign discriminator fields, it is recommended to refactor object into 2 objects like this:

lib/pure/os.nim

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,35 @@ proc splitPath*(path: string): tuple[head, tail: string] {.
276276
result.head = ""
277277
result.tail = path
278278

279+
proc absolutePrefix*(path: string): string {.since: (1, 1).} =
280+
## returns the root path component for absolute paths, empty for relative paths.
281+
## See also `isAbsolute`.
282+
runnableExamples:
283+
when defined(posix):
284+
doAssert absolutePrefix("//foo") == "//"
285+
doAssert absolutePrefix("foo") == ""
286+
when defined(windows):
287+
doAssert absolutePrefix(r"C:\\\bar") == r"C:\\\"
288+
var i = 0
289+
let len = len(path)
290+
when doslikeFileSystem:
291+
while i < len:
292+
if path[i] in {DirSep, AltSep}: i.inc
293+
elif i == 0 and path[0] in {'a'..'z', 'A'..'Z'} and len > 1 and path[1] == ':': i.inc
294+
else: break
295+
elif defined(macos):
296+
# according to https://perldoc.perl.org/File/Spec/Mac.html `:a` is a relative path
297+
while i < len:
298+
if path[i] != ':': i.inc
299+
else: break
300+
elif defined(RISCOS):
301+
if len > 0 and path[0] == '$': i = 1
302+
elif defined(posix):
303+
while i < len:
304+
if path[i] == '/': i.inc
305+
else: break
306+
result = path[0 ..< i]
307+
279308
proc isAbsolute*(path: string): bool {.rtl, noSideEffect, extern: "nos$1", raises: [].} =
280309
## Checks whether a given `path` is absolute.
281310
##
@@ -817,6 +846,21 @@ proc cmpPaths*(pathA, pathB: string): int {.
817846
else:
818847
result = cmpIgnoreCase(a, b)
819848

849+
proc nativeToUnixPath*(path: string): string {.noSideEffect, since: (1, 1).} =
850+
## Converts a native path to a UNIX path; on windows, the drive is converted to
851+
## `/`.
852+
## See also `unixToNativePath`.
853+
runnableExamples:
854+
when defined(windows):
855+
doAssert nativeToUnixPath(r"C:\foo\bar") == "/foo/bar"
856+
when defined(posix):
857+
result = path
858+
else:
859+
let prefix = path.absolutePrefix
860+
if prefix.len > 0:
861+
result.add '/'
862+
result.add path.replace('\\', '/')
863+
820864
proc unixToNativePath*(path: string, drive=""): string {.
821865
noSideEffect, rtl, extern: "nos$1".} =
822866
## Converts an UNIX-like path to a native one.
@@ -828,6 +872,7 @@ proc unixToNativePath*(path: string, drive=""): string {.
828872
## which drive label to use during absolute path conversion.
829873
## `drive` defaults to the drive of the current working directory, and is
830874
## ignored on systems that do not have a concept of "drives".
875+
## See also `nativeToUnixPath`.
831876
when defined(unix):
832877
result = path
833878
else:

0 commit comments

Comments
 (0)