summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--lib/pure/os.nim27
-rw-r--r--tests/stdlib/tos.nim19
2 files changed, 26 insertions, 20 deletions
diff --git a/lib/pure/os.nim b/lib/pure/os.nim
index 5541e6f15..5c387ec03 100644
--- a/lib/pure/os.nim
+++ b/lib/pure/os.nim
@@ -2553,25 +2553,14 @@ proc createDir*(dir: string) {.rtl, extern: "nos$1",
   ## * `copyDir proc`_
   ## * `copyDirWithPermissions proc`_
   ## * `moveDir proc`_
-  var omitNext = false
-  when doslikeFileSystem:
-    var start = 1
-    if isAbsolute(dir):
-      omitNext = true
-      start = dir.splitDrive.drive.len + 1
-  else:
-    let start = 1
-  for i in start.. dir.len-1:
-    if dir[i] in {DirSep, AltSep}:
-      if omitNext:
-        omitNext = false
-      else:
-        discard existsOrCreateDir(substr(dir, 0, i-1))
-
-  # The loop does not create the dir itself if it doesn't end in separator
-  if dir.len > 0 and not omitNext and
-     dir[^1] notin {DirSep, AltSep}:
-    discard existsOrCreateDir(dir)
+  if dir == "":
+    return
+  var omitNext = isAbsolute(dir)
+  for p in parentDirs(dir, fromRoot=true):
+    if omitNext:
+      omitNext = false
+    else:
+      discard existsOrCreateDir(p)
 
 proc copyDir*(source, dest: string) {.rtl, extern: "nos$1",
   tags: [ReadDirEffect, WriteIOEffect, ReadIOEffect], benign, noWeirdTarget.} =
diff --git a/tests/stdlib/tos.nim b/tests/stdlib/tos.nim
index 08088d707..d02fed714 100644
--- a/tests/stdlib/tos.nim
+++ b/tests/stdlib/tos.nim
@@ -156,6 +156,9 @@ block fileOperations:
   doAssert fileExists("../dest/a/file.txt")
   removeDir("../dest")
 
+  # createDir should not fail if `dir` is empty
+  createDir("")
+
   # Symlink handling in `copyFile`, `copyFileWithPermissions`, `copyFileToDir`,
   # `copyDir`, `copyDirWithPermissions`, `moveFile`, and `moveDir`.
   block:
@@ -712,8 +715,10 @@ block: # isAdmin
   # In Azure on POSIX tests run as a normal user
   if isAzure and defined(posix): doAssert not isAdmin()
 
+import std/sequtils
+
 when doslikeFileSystem:
-  import std/[sequtils, private/ntpath]
+  import std/private/ntpath
 
   block: # Bug #19103 UNC paths
 
@@ -775,3 +780,15 @@ when doslikeFileSystem:
     doAssert splitFile("//?/c:") == ("//?/c:", "", "")
     doAssert splitFile("//?/c:/Users") == ("//?/c:", "Users", "")
     doAssert splitFile(r"\\localhost\c$\test.txt") == (r"\\localhost\c$", "test", ".txt")
+
+else:
+  block: # parentDirs
+    doAssert parentDirs("/home", fromRoot=true).toSeq == @["/", "/home"]
+    doAssert parentDirs("/home", fromRoot=false).toSeq == @["/home", "/"]
+    doAssert parentDirs("home", fromRoot=true).toSeq == @["home"]
+    doAssert parentDirs("home", fromRoot=false).toSeq == @["home"]
+
+    doAssert parentDirs("/home/user", fromRoot=true).toSeq == @["/", "/home/", "/home/user"]
+    doAssert parentDirs("/home/user", fromRoot=false).toSeq == @["/home/user", "/home", "/"]
+    doAssert parentDirs("home/user", fromRoot=true).toSeq == @["home/", "home/user"]
+    doAssert parentDirs("home/user", fromRoot=false).toSeq == @["home/user", "home"]