mirror of
https://github.com/nim-lang/Nim.git
synced 2026-05-04 21:14:48 +00:00
Merge branch 'master' of github.com:Araq/Nimrod
This commit is contained in:
@@ -567,26 +567,45 @@ proc isAbsolute*(path: string): bool {.rtl, noSideEffect, extern: "nos$1".} =
|
||||
result = path[0] == '/'
|
||||
|
||||
proc sameFile*(path1, path2: string): bool {.rtl, extern: "nos$1".} =
|
||||
## Returns True if both pathname arguments refer to the same file or
|
||||
## directory (as indicated by device number and i-node number).
|
||||
## Raises an exception if an stat() call on either pathname fails.
|
||||
## Returns True if both pathname arguments refer to the same physical
|
||||
## file or directory. Raises an exception if any of the files does not
|
||||
## exist or information about it can not be obtained.
|
||||
##
|
||||
## This proc will return true if given two alternative hard-linked or
|
||||
## sym-linked paths to the same file or directory.
|
||||
when defined(Windows):
|
||||
var
|
||||
a, b: TWin32FindData
|
||||
var resA = findfirstFileA(path1, a)
|
||||
var resB = findfirstFileA(path2, b)
|
||||
if resA != -1 and resB != -1:
|
||||
result = $a.cFileName == $b.cFileName
|
||||
else:
|
||||
# work around some ``findfirstFileA`` bugs
|
||||
result = cmpPaths(path1, path2) == 0
|
||||
if resA != -1: findclose(resA)
|
||||
if resB != -1: findclose(resB)
|
||||
var success = true
|
||||
|
||||
template OpenHandle(path: expr): expr =
|
||||
CreateFileA(path, 0'i32, FILE_SHARE_DELETE or FILE_SHARE_READ or
|
||||
FILE_SHARE_WRITE, nil, OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS or FILE_ATTRIBUTE_NORMAL, 0)
|
||||
|
||||
var f1 = OpenHandle(path1)
|
||||
var f2 = OpenHandle(path2)
|
||||
|
||||
if f1 != INVALID_HANDLE_VALUE and f2 != INVALID_HANDLE_VALUE:
|
||||
var fi1, fi2: TBY_HANDLE_FILE_INFORMATION
|
||||
|
||||
if GetFileInformationByHandle(f1, addr(fi1)) != 0 and
|
||||
GetFileInformationByHandle(f2, addr(fi2)) != 0:
|
||||
result = fi1.dwVolumeSerialNumber == fi2.dwVolumeSerialNumber and
|
||||
fi1.nFileIndexHigh == fi2.nFileIndexHigh and
|
||||
fi1.nFileIndexLow == fi2.nFileIndexLow
|
||||
else: success = false
|
||||
else: success = false
|
||||
|
||||
discard CloseHandle(f1)
|
||||
discard CloseHandle(f2)
|
||||
|
||||
if not success:
|
||||
OSError()
|
||||
|
||||
else:
|
||||
var
|
||||
a, b: TStat
|
||||
if stat(path1, a) < 0'i32 or stat(path2, b) < 0'i32:
|
||||
result = cmpPaths(path1, path2) == 0 # be consistent with Windows
|
||||
OSError()
|
||||
else:
|
||||
result = a.st_dev == b.st_dev and a.st_ino == b.st_ino
|
||||
|
||||
|
||||
@@ -302,7 +302,7 @@ when not defined(ECMAScript):
|
||||
posix_gettimeofday(a)
|
||||
result = toFloat(a.tv_sec) + toFloat(a.tv_usec)*0.00_0001
|
||||
elif defined(windows):
|
||||
var f: winlean.Filetime
|
||||
var f: winlean.TFiletime
|
||||
GetSystemTimeAsFileTime(f)
|
||||
var i64 = rdFileTime(f) - epochDiff
|
||||
var secs = i64 div rateDiff
|
||||
|
||||
@@ -70,6 +70,10 @@ template test*(name: expr, body: stmt): stmt =
|
||||
TestSetupIMPL()
|
||||
body
|
||||
|
||||
except:
|
||||
checkpoint("Unhandled exception: " & getCurrentExceptionMsg())
|
||||
fail()
|
||||
|
||||
finally:
|
||||
TestTeardownIMPL()
|
||||
testDone name, TestStatusIMPL
|
||||
|
||||
@@ -47,6 +47,22 @@ type
|
||||
dwProcessId*: int32
|
||||
dwThreadId*: int32
|
||||
|
||||
TFILETIME* {.final, pure.} = object ## CANNOT BE int64 BECAUSE OF ALIGNMENT
|
||||
dwLowDateTime*: DWORD
|
||||
dwHighDateTime*: DWORD
|
||||
|
||||
TBY_HANDLE_FILE_INFORMATION* {.final, pure.} = object
|
||||
dwFileAttributes*: DWORD
|
||||
ftCreationTime*: TFILETIME
|
||||
ftLastAccessTime*: TFILETIME
|
||||
ftLastWriteTime*: TFILETIME
|
||||
dwVolumeSerialNumber*: DWORD
|
||||
nFileSizeHigh*: DWORD
|
||||
nFileSizeLow*: DWORD
|
||||
nNumberOfLinks*: DWORD
|
||||
nFileIndexHigh*: DWORD
|
||||
nFileIndexLow*: DWORD
|
||||
|
||||
const
|
||||
STARTF_USESHOWWINDOW* = 1'i32
|
||||
STARTF_USESTDHANDLES* = 256'i32
|
||||
@@ -149,14 +165,11 @@ const
|
||||
|
||||
MAX_PATH* = 260
|
||||
type
|
||||
FILETIME* {.final, pure.} = object ## CANNOT BE int64 BECAUSE OF ALIGNMENT
|
||||
dwLowDateTime*: int32
|
||||
dwHighDateTime*: int32
|
||||
TWIN32_FIND_DATA* {.pure.} = object
|
||||
dwFileAttributes*: int32
|
||||
ftCreationTime*: FILETIME
|
||||
ftLastAccessTime*: FILETIME
|
||||
ftLastWriteTime*: FILETIME
|
||||
ftCreationTime*: TFILETIME
|
||||
ftLastAccessTime*: TFILETIME
|
||||
ftLastWriteTime*: TFILETIME
|
||||
nFileSizeHigh*: int32
|
||||
nFileSizeLow*: int32
|
||||
dwReserved0: int32
|
||||
@@ -192,13 +205,13 @@ proc FreeEnvironmentStringsA*(para1: cstring): int32 {.
|
||||
|
||||
proc GetCommandLineA*(): CString {.importc, stdcall, dynlib: "kernel32".}
|
||||
|
||||
proc rdFileTime*(f: FILETIME): int64 =
|
||||
proc rdFileTime*(f: TFILETIME): int64 =
|
||||
result = ze64(f.dwLowDateTime) or (ze64(f.dwHighDateTime) shl 32)
|
||||
|
||||
proc rdFileSize*(f: TWin32FindData): int64 =
|
||||
result = ze64(f.nFileSizeLow) or (ze64(f.nFileSizeHigh) shl 32)
|
||||
|
||||
proc GetSystemTimeAsFileTime*(lpSystemTimeAsFileTime: var FileTime) {.
|
||||
proc GetSystemTimeAsFileTime*(lpSystemTimeAsFileTime: var TFILETIME) {.
|
||||
importc: "GetSystemTimeAsFileTime", dynlib: "kernel32", stdcall.}
|
||||
|
||||
proc Sleep*(dwMilliseconds: int32){.stdcall, dynlib: "kernel32",
|
||||
@@ -209,12 +222,16 @@ proc ShellExecute*(HWND: THandle, lpOperation, lpFile,
|
||||
nShowCmd: int32): THandle{.
|
||||
stdcall, dynlib: "shell32.dll", importc: "ShellExecuteA".}
|
||||
|
||||
proc GetFileInformationByHandle*(hFile: THandle,
|
||||
lpFileInformation: ptr TBY_HANDLE_FILE_INFORMATION): WINBOOL{.
|
||||
stdcall, dynlib: "kernel32", importc: "GetFileInformationByHandle".}
|
||||
|
||||
const
|
||||
WSADESCRIPTION_LEN* = 256
|
||||
WSASYS_STATUS_LEN* = 128
|
||||
FD_SETSIZE* = 64
|
||||
MSG_PEEK* = 2
|
||||
|
||||
|
||||
INADDR_ANY* = 0
|
||||
INADDR_LOOPBACK* = 0x7F000001
|
||||
INADDR_BROADCAST* = -1
|
||||
@@ -410,6 +427,9 @@ const
|
||||
GENERIC_READ* = 0x80000000'i32
|
||||
GENERIC_ALL* = 0x10000000'i32
|
||||
FILE_SHARE_READ* = 1'i32
|
||||
FILE_SHARE_DELETE* = 4'i32
|
||||
FILE_SHARE_WRITE* = 2'i32
|
||||
|
||||
CREATE_ALWAYS* = 2'i32
|
||||
OPEN_EXISTING* = 3'i32
|
||||
FILE_BEGIN* = 0'i32
|
||||
@@ -421,6 +441,8 @@ const
|
||||
FILE_MAP_WRITE* = 2'i32
|
||||
INVALID_FILE_SIZE* = -1'i32
|
||||
|
||||
FILE_FLAG_BACKUP_SEMANTICS* = 33554432'i32
|
||||
|
||||
proc CreateFileA*(lpFileName: cstring, dwDesiredAccess, dwShareMode: DWORD,
|
||||
lpSecurityAttributes: pointer,
|
||||
dwCreationDisposition, dwFlagsAndAttributes: DWORD,
|
||||
|
||||
Reference in New Issue
Block a user