summary refs log tree commit diff stats
path: root/lib/std/private
diff options
context:
space:
mode:
Diffstat (limited to 'lib/std/private')
-rw-r--r--lib/std/private/gitutils.nim13
-rw-r--r--lib/std/private/jsutils.nim6
-rw-r--r--lib/std/private/osdirs.nim21
-rw-r--r--lib/std/private/osfiles.nim2
-rw-r--r--lib/std/private/ospaths2.nim16
-rw-r--r--lib/std/private/ossymlinks.nim18
-rw-r--r--lib/std/private/syslocks.nim28
7 files changed, 54 insertions, 50 deletions
diff --git a/lib/std/private/gitutils.nim b/lib/std/private/gitutils.nim
index db323bee1..6dc9c8f3b 100644
--- a/lib/std/private/gitutils.nim
+++ b/lib/std/private/gitutils.nim
@@ -4,7 +4,7 @@ internal API for now, API subject to change
 
 # xxx move other git utilities here; candidate for stdlib.
 
-import std/[os, osproc, strutils, tempfiles]
+import std/[os, paths, osproc, strutils, tempfiles]
 
 when defined(nimPreviewSlimSystem):
   import std/[assertions, syncio]
@@ -32,15 +32,8 @@ template retryCall*(maxRetry = 3, backoffDuration = 1.0, call: untyped): bool =
   result
 
 proc isGitRepo*(dir: string): bool =
-  ## This command is used to get the relative path to the root of the repository.
-  ## Using this, we can verify whether a folder is a git repository by checking
-  ## whether the command success and if the output is empty.
-  let (output, status) = execCmdEx("git rev-parse --show-cdup", workingDir = dir)
-  # On Windows there will be a trailing newline on success, remove it.
-  # The value of a successful call typically won't have a whitespace (it's
-  # usually a series of ../), so we know that it's safe to unconditionally
-  # remove trailing whitespaces from the result.
-  result = status == 0 and output.strip() == ""
+  ## Avoid calling git since it depends on /bin/sh existing and fails in Nix.
+  return fileExists(dir/".git/HEAD")
 
 proc diffFiles*(path1, path2: string): tuple[output: string, same: bool] =
   ## Returns a human readable diff of files `path1`, `path2`, the exact form of
diff --git a/lib/std/private/jsutils.nim b/lib/std/private/jsutils.nim
index fd1f395f3..5f79eab27 100644
--- a/lib/std/private/jsutils.nim
+++ b/lib/std/private/jsutils.nim
@@ -37,13 +37,13 @@ when defined(js):
       let a = array[2, float64].default
       assert jsConstructorName(a) == "Float64Array"
       assert jsConstructorName(a.toJs) == "Float64Array"
-    asm """`result` = `a`.constructor.name"""
+    {.emit: """`result` = `a`.constructor.name;""".}
 
   proc hasJsBigInt*(): bool =
-    asm """`result` = typeof BigInt != 'undefined'"""
+    {.emit: """`result` = typeof BigInt != 'undefined';""".}
 
   proc hasBigUint64Array*(): bool =
-    asm """`result` = typeof BigUint64Array != 'undefined'"""
+    {.emit: """`result` = typeof BigUint64Array != 'undefined';""".}
 
   proc getProtoName*[T](a: T): cstring {.importjs: "Object.prototype.toString.call(#)".} =
     runnableExamples:
diff --git a/lib/std/private/osdirs.nim b/lib/std/private/osdirs.nim
index b89a59c8d..a44cad7d9 100644
--- a/lib/std/private/osdirs.nim
+++ b/lib/std/private/osdirs.nim
@@ -446,13 +446,17 @@ proc createDir*(dir: string) {.rtl, extern: "nos$1",
     else:
       discard existsOrCreateDir(p)
 
-proc copyDir*(source, dest: string) {.rtl, extern: "nos$1",
+proc copyDir*(source, dest: string, skipSpecial = false) {.rtl, extern: "nos$1",
   tags: [ReadDirEffect, WriteIOEffect, ReadIOEffect], benign, noWeirdTarget.} =
   ## Copies a directory from `source` to `dest`.
   ##
   ## On non-Windows OSes, symlinks are copied as symlinks. On Windows, symlinks
   ## are skipped.
   ##
+  ## If `skipSpecial` is true, then (besides all directories) only *regular*
+  ## files (**without** special "file" objects like FIFOs, device files,
+  ## etc) will be copied on Unix.
+  ##
   ## If this fails, `OSError` is raised.
   ##
   ## On the Windows platform this proc will copy the attributes from
@@ -472,16 +476,17 @@ proc copyDir*(source, dest: string) {.rtl, extern: "nos$1",
   ## * `createDir proc`_
   ## * `moveDir proc`_
   createDir(dest)
-  for kind, path in walkDir(source):
+  for kind, path in walkDir(source, skipSpecial = skipSpecial):
     var noSource = splitPath(path).tail
     if kind == pcDir:
-      copyDir(path, dest / noSource)
+      copyDir(path, dest / noSource, skipSpecial = skipSpecial)
     else:
       copyFile(path, dest / noSource, {cfSymlinkAsIs})
 
 
 proc copyDirWithPermissions*(source, dest: string,
-                             ignorePermissionErrors = true)
+                             ignorePermissionErrors = true,
+                             skipSpecial = false)
   {.rtl, extern: "nos$1", tags: [ReadDirEffect, WriteIOEffect, ReadIOEffect],
    benign, noWeirdTarget.} =
   ## Copies a directory from `source` to `dest` preserving file permissions.
@@ -489,6 +494,10 @@ proc copyDirWithPermissions*(source, dest: string,
   ## On non-Windows OSes, symlinks are copied as symlinks. On Windows, symlinks
   ## are skipped.
   ##
+  ## If `skipSpecial` is true, then (besides all directories) only *regular*
+  ## files (**without** special "file" objects like FIFOs, device files,
+  ## etc) will be copied on Unix.
+  ##
   ## If this fails, `OSError` is raised. This is a wrapper proc around
   ## `copyDir`_ and `copyFileWithPermissions`_ procs
   ## on non-Windows platforms.
@@ -518,10 +527,10 @@ proc copyDirWithPermissions*(source, dest: string,
     except:
       if not ignorePermissionErrors:
         raise
-  for kind, path in walkDir(source):
+  for kind, path in walkDir(source, skipSpecial = skipSpecial):
     var noSource = splitPath(path).tail
     if kind == pcDir:
-      copyDirWithPermissions(path, dest / noSource, ignorePermissionErrors)
+      copyDirWithPermissions(path, dest / noSource, ignorePermissionErrors, skipSpecial = skipSpecial)
     else:
       copyFileWithPermissions(path, dest / noSource, ignorePermissionErrors, {cfSymlinkAsIs})
 
diff --git a/lib/std/private/osfiles.nim b/lib/std/private/osfiles.nim
index a1d7079c5..37d8eabca 100644
--- a/lib/std/private/osfiles.nim
+++ b/lib/std/private/osfiles.nim
@@ -240,7 +240,7 @@ proc copyFile*(source, dest: string, options = {cfSymlinkFollow}; bufferSize = 1
       else:
         # generic version of copyFile which works for any platform:
         var d, s: File
-        if not open(s, source):raiseOSError(osLastError(), source)
+        if not open(s, source): raiseOSError(osLastError(), source)
         if not open(d, dest, fmWrite):
           close(s)
           raiseOSError(osLastError(), dest)
diff --git a/lib/std/private/ospaths2.nim b/lib/std/private/ospaths2.nim
index 37fae3ccd..bc69ff725 100644
--- a/lib/std/private/ospaths2.nim
+++ b/lib/std/private/ospaths2.nim
@@ -254,10 +254,10 @@ 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:
     raiseAssert "unreachable" # if ever hits here, adapt as needed
 
@@ -763,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
@@ -862,13 +862,13 @@ when not defined(nimscript):
       raiseAssert "use -d:nodejs to have `getCurrentDir` defined"
     elif defined(windows):
       var bufsize = MAX_PATH.int32
-      var res = newWideCString("", bufsize)
+      var res = newWideCString(bufsize)
       while true:
         var L = getCurrentDirectoryW(bufsize, res)
         if L == 0'i32:
           raiseOSError(osLastError())
         elif L > bufsize:
-          res = newWideCString("", L)
+          res = newWideCString(L)
           bufsize = L
         else:
           result = res$L
diff --git a/lib/std/private/ossymlinks.nim b/lib/std/private/ossymlinks.nim
index c0774b573..c1760c42e 100644
--- a/lib/std/private/ossymlinks.nim
+++ b/lib/std/private/ossymlinks.nim
@@ -66,11 +66,13 @@ proc expandSymlink*(symlinkPath: string): string {.noWeirdTarget.} =
   when defined(windows) or defined(nintendoswitch):
     result = symlinkPath
   else:
-    result = newString(maxSymlinkLen)
-    var len = readlink(symlinkPath, result.cstring, maxSymlinkLen)
-    if len < 0:
-      raiseOSError(osLastError(), symlinkPath)
-    if len > maxSymlinkLen:
-      result = newString(len+1)
-      len = readlink(symlinkPath, result.cstring, len)
-    setLen(result, len)
+    var bufLen = 1024
+    while true:
+      result = newString(bufLen)
+      let len = readlink(symlinkPath.cstring, result.cstring, bufLen)
+      if len < 0:
+        raiseOSError(osLastError(), symlinkPath)
+      if len < bufLen:
+        result.setLen(len)
+        break
+      bufLen = bufLen shl 1
diff --git a/lib/std/private/syslocks.nim b/lib/std/private/syslocks.nim
index ca8897dc2..e19ec2c04 100644
--- a/lib/std/private/syslocks.nim
+++ b/lib/std/private/syslocks.nim
@@ -16,7 +16,7 @@ when defined(windows):
     Handle = int
 
     SysLock* {.importc: "CRITICAL_SECTION",
-              header: "<windows.h>", final, pure.} = object # CRITICAL_SECTION in WinApi
+              header: "<windows.h>", final, pure, byref.} = object # CRITICAL_SECTION in WinApi
       DebugInfo: pointer
       LockCount: int32
       RecursionCount: int32
@@ -24,7 +24,7 @@ when defined(windows):
       LockSemaphore: int
       SpinCount: int
 
-    SysCond* {.importc: "RTL_CONDITION_VARIABLE", header: "<windows.h>".} = object
+    SysCond* {.importc: "RTL_CONDITION_VARIABLE", header: "<windows.h>", byref.} = object
       thePtr {.importc: "Ptr".} : Handle
 
   proc initSysLock*(L: var SysLock) {.importc: "InitializeCriticalSection",
@@ -46,7 +46,7 @@ when defined(windows):
                                     header: "<windows.h>".}
     ## Releases the lock `L`.
 
-  proc deinitSys*(L: var SysLock) {.importc: "DeleteCriticalSection",
+  proc deinitSys*(L: SysLock) {.importc: "DeleteCriticalSection",
                                    header: "<windows.h>".}
 
   proc initializeConditionVariable(
@@ -68,7 +68,7 @@ when defined(windows):
 
   proc initSysCond*(cond: var SysCond) {.inline.} =
     initializeConditionVariable(cond)
-  proc deinitSysCond*(cond: var SysCond) {.inline.} =
+  proc deinitSysCond*(cond: SysCond) {.inline.} =
     discard
   proc waitSysCond*(cond: var SysCond, lock: var SysLock) =
     discard sleepConditionVariableCS(cond, lock, -1'i32)
@@ -83,13 +83,13 @@ elif defined(genode):
               header: Header.} = object
 
   proc initSysLock*(L: var SysLock) = discard
-  proc deinitSys*(L: var SysLock) = discard
+  proc deinitSys*(L: SysLock) = discard
   proc acquireSys*(L: var SysLock) {.noSideEffect, importcpp.}
   proc tryAcquireSys*(L: var SysLock): bool {.noSideEffect, importcpp.}
   proc releaseSys*(L: var SysLock) {.noSideEffect, importcpp.}
 
   proc initSysCond*(L: var SysCond) = discard
-  proc deinitSysCond*(L: var SysCond) = discard
+  proc deinitSysCond*(L: SysCond) = discard
   proc waitSysCond*(cond: var SysCond, lock: var SysLock) {.
     noSideEffect, importcpp.}
   proc signalSysCond*(cond: var SysCond) {.
@@ -101,7 +101,7 @@ else:
   type
     SysLockObj {.importc: "pthread_mutex_t", pure, final,
                header: """#include <sys/types.h>
-                          #include <pthread.h>""".} = object
+                          #include <pthread.h>""", byref.} = object
       when defined(linux) and defined(amd64):
         abi: array[40 div sizeof(clong), clong]
 
@@ -113,7 +113,7 @@ else:
 
     SysCondObj {.importc: "pthread_cond_t", pure, final,
                header: """#include <sys/types.h>
-                          #include <pthread.h>""".} = object
+                          #include <pthread.h>""", byref.} = object
       when defined(linux) and defined(amd64):
         abi: array[48 div sizeof(clonglong), clonglong]
 
@@ -127,7 +127,7 @@ else:
 
   proc initSysLockAux(L: var SysLockObj, attr: ptr SysLockAttr) {.
     importc: "pthread_mutex_init", header: "<pthread.h>", noSideEffect.}
-  proc deinitSysAux(L: var SysLockObj) {.noSideEffect,
+  proc deinitSysAux(L: SysLockObj) {.noSideEffect,
     importc: "pthread_mutex_destroy", header: "<pthread.h>".}
 
   proc acquireSysAux(L: var SysLockObj) {.noSideEffect,
@@ -156,7 +156,7 @@ else:
       L = cast[SysLock](c_malloc(csize_t(sizeof(SysLockObj))))
       initSysLockAux(L[], attr)
 
-    proc deinitSys*(L: var SysLock) =
+    proc deinitSys*(L: SysLock) =
       deinitSysAux(L[])
       c_free(L)
 
@@ -173,7 +173,7 @@ else:
 
     template initSysLock*(L: var SysLock, attr: ptr SysLockAttr = nil) =
       initSysLockAux(L, attr)
-    template deinitSys*(L: var SysLock) =
+    template deinitSys*(L: SysLock) =
       deinitSysAux(L)
     template acquireSys*(L: var SysLock) =
       acquireSysAux(L)
@@ -193,7 +193,7 @@ else:
   # locks
   proc initSysCondAux(cond: var SysCondObj, cond_attr: ptr SysCondAttr = nil) {.
     importc: "pthread_cond_init", header: "<pthread.h>", noSideEffect.}
-  proc deinitSysCondAux(cond: var SysCondObj) {.noSideEffect,
+  proc deinitSysCondAux(cond: SysCondObj) {.noSideEffect,
     importc: "pthread_cond_destroy", header: "<pthread.h>".}
 
   proc waitSysCondAux(cond: var SysCondObj, lock: var SysLockObj): cint {.
@@ -208,7 +208,7 @@ else:
       cond = cast[SysCond](c_malloc(csize_t(sizeof(SysCondObj))))
       initSysCondAux(cond[], cond_attr)
 
-    proc deinitSysCond*(cond: var SysCond) =
+    proc deinitSysCond*(cond: SysCond) =
       deinitSysCondAux(cond[])
       c_free(cond)
 
@@ -221,7 +221,7 @@ else:
   else:
     template initSysCond*(cond: var SysCond, cond_attr: ptr SysCondAttr = nil) =
       initSysCondAux(cond, cond_attr)
-    template deinitSysCond*(cond: var SysCond) =
+    template deinitSysCond*(cond: SysCond) =
       deinitSysCondAux(cond)
 
     template waitSysCond*(cond: var SysCond, lock: var SysLock) =