Merge branch 'master' of github.com:Araq/Nimrod

This commit is contained in:
Araq
2011-12-12 01:40:47 +01:00
24 changed files with 223 additions and 146 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -70,6 +70,10 @@ template test*(name: expr, body: stmt): stmt =
TestSetupIMPL()
body
except:
checkpoint("Unhandled exception: " & getCurrentExceptionMsg())
fail()
finally:
TestTeardownIMPL()
testDone name, TestStatusIMPL

View File

@@ -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,