mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-13 14:53:46 +00:00
Merge pull request #4284 from arnetheduck/system-c-cleanup
System c cleanup
This commit is contained in:
@@ -347,9 +347,6 @@ static N_INLINE(NI32, float32ToInt32)(float x) {
|
||||
|
||||
#define float64ToInt64(x) ((NI64) (x))
|
||||
|
||||
#define zeroMem(a, size) memset(a, 0, size)
|
||||
#define equalMem(a, b, size) (memcmp(a, b, size) == 0)
|
||||
|
||||
#define STRING_LITERAL(name, str, length) \
|
||||
static const struct { \
|
||||
TGenericSeq Sup; \
|
||||
|
||||
@@ -257,12 +257,10 @@ type MemSlice* = object ## represent slice of a MemFile for iteration over deli
|
||||
data*: pointer
|
||||
size*: int
|
||||
|
||||
proc c_memcpy(a, b: pointer, n: int) {.importc: "memcpy", header: "<string.h>".}
|
||||
|
||||
proc `$`*(ms: MemSlice): string {.inline.} =
|
||||
## Return a Nim string built from a MemSlice.
|
||||
var buf = newString(ms.size)
|
||||
c_memcpy(addr(buf[0]), ms.data, ms.size)
|
||||
copyMem(addr(buf[0]), ms.data, ms.size)
|
||||
buf[ms.size] = '\0'
|
||||
result = buf
|
||||
|
||||
@@ -329,7 +327,7 @@ iterator lines*(mfile: MemFile, buf: var TaintedString, delim='\l', eat='\r'): T
|
||||
|
||||
for ms in memSlices(mfile, delim, eat):
|
||||
buf.setLen(ms.size)
|
||||
c_memcpy(addr(buf[0]), ms.data, ms.size)
|
||||
copyMem(addr(buf[0]), ms.data, ms.size)
|
||||
buf[ms.size] = '\0'
|
||||
yield buf
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ elif defined(posix):
|
||||
else:
|
||||
{.error: "OS module not ported to your operating system!".}
|
||||
|
||||
include "system/ansi_c"
|
||||
include ospaths
|
||||
|
||||
when defined(posix):
|
||||
@@ -37,6 +36,23 @@ when defined(posix):
|
||||
var
|
||||
pathMax {.importc: "PATH_MAX", header: "<stdlib.h>".}: cint
|
||||
|
||||
proc c_remove(filename: cstring): cint {.
|
||||
importc: "remove", header: "<stdio.h>".}
|
||||
proc c_rename(oldname, newname: cstring): cint {.
|
||||
importc: "rename", header: "<stdio.h>".}
|
||||
proc c_system(cmd: cstring): cint {.
|
||||
importc: "system", header: "<stdlib.h>".}
|
||||
proc c_strerror(errnum: cint): cstring {.
|
||||
importc: "strerror", header: "<string.h>".}
|
||||
proc c_strlen(a: cstring): cint {.
|
||||
importc: "strlen", header: "<string.h>", noSideEffect.}
|
||||
proc c_getenv(env: cstring): cstring {.
|
||||
importc: "getenv", header: "<stdlib.h>".}
|
||||
proc c_putenv(env: cstring): cint {.
|
||||
importc: "putenv", header: "<stdlib.h>".}
|
||||
|
||||
var errno {.importc, header: "<errno.h>".}: cint
|
||||
|
||||
proc osErrorMsg*(): string {.rtl, extern: "nos$1", deprecated.} =
|
||||
## Retrieves the operating system's error flag, ``errno``.
|
||||
## On Windows ``GetLastError`` is checked before ``errno``.
|
||||
@@ -61,7 +77,7 @@ proc osErrorMsg*(): string {.rtl, extern: "nos$1", deprecated.} =
|
||||
result = $msgbuf
|
||||
if msgbuf != nil: localFree(msgbuf)
|
||||
if errno != 0'i32:
|
||||
result = $os.strerror(errno)
|
||||
result = $os.c_strerror(errno)
|
||||
|
||||
{.push warning[deprecated]: off.}
|
||||
proc raiseOSError*(msg: string = "") {.noinline, rtl, extern: "nos$1",
|
||||
@@ -114,7 +130,7 @@ proc osErrorMsg*(errorCode: OSErrorCode): string =
|
||||
if msgbuf != nil: localFree(msgbuf)
|
||||
else:
|
||||
if errorCode != OSErrorCode(0'i32):
|
||||
result = $os.strerror(errorCode.int32)
|
||||
result = $os.c_strerror(errorCode.int32)
|
||||
|
||||
proc raiseOSError*(errorCode: OSErrorCode; additionalInfo = "") {.noinline.} =
|
||||
## Raises an ``OSError`` exception. The ``errorCode`` will determine the
|
||||
|
||||
@@ -306,67 +306,67 @@ proc peekLine*(s: Stream): TaintedString =
|
||||
defer: setPosition(s, pos)
|
||||
result = readLine(s)
|
||||
|
||||
type
|
||||
StringStream* = ref StringStreamObj ## a stream that encapsulates a string
|
||||
StringStreamObj* = object of StreamObj
|
||||
data*: string
|
||||
pos: int
|
||||
|
||||
{.deprecated: [PStringStream: StringStream, TStringStream: StringStreamObj].}
|
||||
|
||||
proc ssAtEnd(s: Stream): bool =
|
||||
var s = StringStream(s)
|
||||
return s.pos >= s.data.len
|
||||
|
||||
proc ssSetPosition(s: Stream, pos: int) =
|
||||
var s = StringStream(s)
|
||||
s.pos = clamp(pos, 0, s.data.len)
|
||||
|
||||
proc ssGetPosition(s: Stream): int =
|
||||
var s = StringStream(s)
|
||||
return s.pos
|
||||
|
||||
proc ssReadData(s: Stream, buffer: pointer, bufLen: int): int =
|
||||
var s = StringStream(s)
|
||||
result = min(bufLen, s.data.len - s.pos)
|
||||
if result > 0:
|
||||
copyMem(buffer, addr(s.data[s.pos]), result)
|
||||
inc(s.pos, result)
|
||||
|
||||
proc ssPeekData(s: Stream, buffer: pointer, bufLen: int): int =
|
||||
var s = StringStream(s)
|
||||
result = min(bufLen, s.data.len - s.pos)
|
||||
if result > 0:
|
||||
copyMem(buffer, addr(s.data[s.pos]), result)
|
||||
|
||||
proc ssWriteData(s: Stream, buffer: pointer, bufLen: int) =
|
||||
var s = StringStream(s)
|
||||
if bufLen <= 0:
|
||||
return
|
||||
if s.pos + bufLen > s.data.len:
|
||||
setLen(s.data, s.pos + bufLen)
|
||||
copyMem(addr(s.data[s.pos]), buffer, bufLen)
|
||||
inc(s.pos, bufLen)
|
||||
|
||||
proc ssClose(s: Stream) =
|
||||
var s = StringStream(s)
|
||||
s.data = nil
|
||||
|
||||
proc newStringStream*(s: string = ""): StringStream =
|
||||
## creates a new stream from the string `s`.
|
||||
new(result)
|
||||
result.data = s
|
||||
result.pos = 0
|
||||
result.closeImpl = ssClose
|
||||
result.atEndImpl = ssAtEnd
|
||||
result.setPositionImpl = ssSetPosition
|
||||
result.getPositionImpl = ssGetPosition
|
||||
result.readDataImpl = ssReadData
|
||||
result.peekDataImpl = ssPeekData
|
||||
result.writeDataImpl = ssWriteData
|
||||
|
||||
when not defined(js):
|
||||
|
||||
type
|
||||
StringStream* = ref StringStreamObj ## a stream that encapsulates a string
|
||||
StringStreamObj* = object of StreamObj
|
||||
data*: string
|
||||
pos: int
|
||||
|
||||
{.deprecated: [PStringStream: StringStream, TStringStream: StringStreamObj].}
|
||||
|
||||
proc ssAtEnd(s: Stream): bool =
|
||||
var s = StringStream(s)
|
||||
return s.pos >= s.data.len
|
||||
|
||||
proc ssSetPosition(s: Stream, pos: int) =
|
||||
var s = StringStream(s)
|
||||
s.pos = clamp(pos, 0, s.data.len)
|
||||
|
||||
proc ssGetPosition(s: Stream): int =
|
||||
var s = StringStream(s)
|
||||
return s.pos
|
||||
|
||||
proc ssReadData(s: Stream, buffer: pointer, bufLen: int): int =
|
||||
var s = StringStream(s)
|
||||
result = min(bufLen, s.data.len - s.pos)
|
||||
if result > 0:
|
||||
copyMem(buffer, addr(s.data[s.pos]), result)
|
||||
inc(s.pos, result)
|
||||
|
||||
proc ssPeekData(s: Stream, buffer: pointer, bufLen: int): int =
|
||||
var s = StringStream(s)
|
||||
result = min(bufLen, s.data.len - s.pos)
|
||||
if result > 0:
|
||||
copyMem(buffer, addr(s.data[s.pos]), result)
|
||||
|
||||
proc ssWriteData(s: Stream, buffer: pointer, bufLen: int) =
|
||||
var s = StringStream(s)
|
||||
if bufLen <= 0:
|
||||
return
|
||||
if s.pos + bufLen > s.data.len:
|
||||
setLen(s.data, s.pos + bufLen)
|
||||
copyMem(addr(s.data[s.pos]), buffer, bufLen)
|
||||
inc(s.pos, bufLen)
|
||||
|
||||
proc ssClose(s: Stream) =
|
||||
var s = StringStream(s)
|
||||
s.data = nil
|
||||
|
||||
proc newStringStream*(s: string = ""): StringStream =
|
||||
## creates a new stream from the string `s`.
|
||||
new(result)
|
||||
result.data = s
|
||||
result.pos = 0
|
||||
result.closeImpl = ssClose
|
||||
result.atEndImpl = ssAtEnd
|
||||
result.setPositionImpl = ssSetPosition
|
||||
result.getPositionImpl = ssGetPosition
|
||||
result.readDataImpl = ssReadData
|
||||
result.peekDataImpl = ssPeekData
|
||||
result.writeDataImpl = ssWriteData
|
||||
|
||||
type
|
||||
FileStream* = ref FileStreamObj ## a stream that encapsulates a `File`
|
||||
FileStreamObj* = object of Stream
|
||||
|
||||
@@ -1593,34 +1593,32 @@ proc substr*(s: string, first, last: int): string {.
|
||||
## is used instead: This means ``substr`` can also be used to `cut`:idx:
|
||||
## or `limit`:idx: a string's length.
|
||||
|
||||
when not defined(nimscript):
|
||||
proc zeroMem*(p: pointer, size: Natural) {.importc, noDecl, benign.}
|
||||
when not defined(nimscript) and not defined(JS):
|
||||
proc zeroMem*(p: pointer, size: Natural) {.inline, benign.}
|
||||
## overwrites the contents of the memory at ``p`` with the value 0.
|
||||
## Exactly ``size`` bytes will be overwritten. Like any procedure
|
||||
## dealing with raw memory this is *unsafe*.
|
||||
|
||||
proc copyMem*(dest, source: pointer, size: Natural) {.
|
||||
importc: "memcpy", header: "<string.h>", benign.}
|
||||
proc copyMem*(dest, source: pointer, size: Natural) {.inline, benign.}
|
||||
## copies the contents from the memory at ``source`` to the memory
|
||||
## at ``dest``. Exactly ``size`` bytes will be copied. The memory
|
||||
## regions may not overlap. Like any procedure dealing with raw
|
||||
## memory this is *unsafe*.
|
||||
|
||||
proc moveMem*(dest, source: pointer, size: Natural) {.
|
||||
importc: "memmove", header: "<string.h>", benign.}
|
||||
proc moveMem*(dest, source: pointer, size: Natural) {.inline, benign.}
|
||||
## copies the contents from the memory at ``source`` to the memory
|
||||
## at ``dest``. Exactly ``size`` bytes will be copied. The memory
|
||||
## regions may overlap, ``moveMem`` handles this case appropriately
|
||||
## and is thus somewhat more safe than ``copyMem``. Like any procedure
|
||||
## dealing with raw memory this is still *unsafe*, though.
|
||||
|
||||
proc equalMem*(a, b: pointer, size: Natural): bool {.
|
||||
importc: "equalMem", noDecl, noSideEffect.}
|
||||
proc equalMem*(a, b: pointer, size: Natural): bool {.inline, noSideEffect.}
|
||||
## compares the memory blocks ``a`` and ``b``. ``size`` bytes will
|
||||
## be compared. If the blocks are equal, true is returned, false
|
||||
## otherwise. Like any procedure dealing with raw memory this is
|
||||
## *unsafe*.
|
||||
|
||||
when not defined(nimscript):
|
||||
when hasAlloc:
|
||||
proc alloc*(size: Natural): pointer {.noconv, rtl, tags: [], benign.}
|
||||
## allocates a new memory block with at least ``size`` bytes. The
|
||||
@@ -2618,11 +2616,21 @@ when not defined(JS): #and not defined(nimscript):
|
||||
|
||||
{.deprecated: [TFile: File, TFileHandle: FileHandle, TFileMode: FileMode].}
|
||||
|
||||
when not defined(nimscript):
|
||||
include "system/ansi_c"
|
||||
include "system/ansi_c"
|
||||
|
||||
when not defined(nimscript):
|
||||
proc cmp(x, y: string): int =
|
||||
result = int(c_strcmp(x, y))
|
||||
|
||||
proc zeroMem(p: pointer, size: Natural) =
|
||||
c_memset(p, 0, size)
|
||||
proc copyMem(dest, source: pointer, size: Natural) =
|
||||
c_memcpy(dest, source, size)
|
||||
proc moveMem(dest, source: pointer, size: Natural) =
|
||||
c_memmove(dest, source, size)
|
||||
proc equalMem(a, b: pointer, size: Natural): bool =
|
||||
c_memcmp(a, b, size) == 0
|
||||
|
||||
else:
|
||||
proc cmp(x, y: string): int =
|
||||
if x < y: result = -1
|
||||
@@ -2644,22 +2652,6 @@ when not defined(JS): #and not defined(nimscript):
|
||||
## Raises an IO exception in case of an error.
|
||||
|
||||
when not defined(nimscript) and hostOS != "standalone":
|
||||
when defined(windows):
|
||||
# work-around C's sucking abstraction:
|
||||
# BUGFIX: stdin and stdout should be binary files!
|
||||
proc setmode(handle, mode: int) {.importc: "setmode",
|
||||
header: "<io.h>".}
|
||||
proc fileno(f: C_TextFileStar): int {.importc: "fileno",
|
||||
header: "<fcntl.h>".}
|
||||
var
|
||||
O_BINARY {.importc: "O_BINARY", nodecl.}: int
|
||||
|
||||
# we use binary mode on Windows:
|
||||
setmode(fileno(c_stdin), O_BINARY)
|
||||
setmode(fileno(c_stdout), O_BINARY)
|
||||
|
||||
when defined(endb):
|
||||
proc endbStep()
|
||||
|
||||
# text file handling:
|
||||
var
|
||||
@@ -2670,6 +2662,21 @@ when not defined(JS): #and not defined(nimscript):
|
||||
stderr* {.importc: "stderr", header: "<stdio.h>".}: File
|
||||
## The standard error stream.
|
||||
|
||||
when defined(windows):
|
||||
# work-around C's sucking abstraction:
|
||||
# BUGFIX: stdin and stdout should be binary files!
|
||||
proc c_setmode(handle, mode: cint) {.importc: "_setmode",
|
||||
header: "<io.h>".}
|
||||
var
|
||||
O_BINARY {.importc: "O_BINARY", nodecl.}: cint
|
||||
|
||||
# we use binary mode on Windows:
|
||||
c_setmode(c_fileno(stdin), O_BINARY)
|
||||
c_setmode(c_fileno(stdout), O_BINARY)
|
||||
|
||||
when defined(endb):
|
||||
proc endbStep()
|
||||
|
||||
when defined(useStdoutAsStdmsg):
|
||||
template stdmsg*: File = stdout
|
||||
else:
|
||||
@@ -2708,17 +2715,16 @@ when not defined(JS): #and not defined(nimscript):
|
||||
##
|
||||
## Default mode is readonly. Returns true iff the file could be reopened.
|
||||
|
||||
proc close*(f: File) {.importc: "fclose", header: "<stdio.h>", tags: [].}
|
||||
proc close*(f: File) {.tags: [].}
|
||||
## Closes the file.
|
||||
|
||||
proc endOfFile*(f: File): bool {.tags: [], benign.}
|
||||
## Returns true iff `f` is at the end.
|
||||
|
||||
proc readChar*(f: File): char {.
|
||||
importc: "fgetc", header: "<stdio.h>", tags: [ReadIOEffect].}
|
||||
proc readChar*(f: File): char {.tags: [ReadIOEffect].}
|
||||
## Reads a single character from the stream `f`.
|
||||
proc flushFile*(f: File) {.
|
||||
importc: "fflush", header: "<stdio.h>", tags: [WriteIOEffect].}
|
||||
|
||||
proc flushFile*(f: File) {.tags: [WriteIOEffect].}
|
||||
## Flushes `f`'s buffer.
|
||||
|
||||
proc readAll*(file: File): TaintedString {.tags: [ReadIOEffect], benign.}
|
||||
@@ -2824,8 +2830,7 @@ when not defined(JS): #and not defined(nimscript):
|
||||
## retrieves the current position of the file pointer that is used to
|
||||
## read from the file `f`. The file's first byte has the index zero.
|
||||
|
||||
proc getFileHandle*(f: File): FileHandle {.importc: "fileno",
|
||||
header: "<stdio.h>"}
|
||||
proc getFileHandle*(f: File): FileHandle
|
||||
## returns the OS file handle of the file ``f``. This is only useful for
|
||||
## platform specific programming.
|
||||
|
||||
|
||||
@@ -324,9 +324,9 @@ proc contains[T](list, x: T): bool =
|
||||
|
||||
proc writeFreeList(a: MemRegion) =
|
||||
var it = a.freeChunksList
|
||||
c_fprintf(c_stdout, "freeChunksList: %p\n", it)
|
||||
c_fprintf(stdout, "freeChunksList: %p\n", it)
|
||||
while it != nil:
|
||||
c_fprintf(c_stdout, "it: %p, next: %p, prev: %p\n",
|
||||
c_fprintf(stdout, "it: %p, next: %p, prev: %p\n",
|
||||
it, it.next, it.prev)
|
||||
it = it.next
|
||||
|
||||
|
||||
@@ -13,60 +13,42 @@
|
||||
|
||||
{.push hints:off}
|
||||
|
||||
proc c_strcmp(a, b: cstring): cint {.header: "<string.h>",
|
||||
noSideEffect, importc: "strcmp".}
|
||||
proc c_memcmp(a, b: cstring, size: int): cint {.header: "<string.h>",
|
||||
noSideEffect, importc: "memcmp".}
|
||||
proc c_memcpy(a, b: cstring, size: int) {.header: "<string.h>", importc: "memcpy".}
|
||||
proc c_strlen(a: cstring): int {.header: "<string.h>",
|
||||
noSideEffect, importc: "strlen".}
|
||||
proc c_memset(p: pointer, value: cint, size: int) {.
|
||||
header: "<string.h>", importc: "memset".}
|
||||
|
||||
when not declared(File):
|
||||
type
|
||||
C_TextFile {.importc: "FILE", header: "<stdio.h>",
|
||||
final, incompleteStruct.} = object
|
||||
C_BinaryFile {.importc: "FILE", header: "<stdio.h>",
|
||||
final, incompleteStruct.} = object
|
||||
C_TextFileStar = ptr C_TextFile
|
||||
C_BinaryFileStar = ptr C_BinaryFile
|
||||
else:
|
||||
type
|
||||
C_TextFileStar = File
|
||||
C_BinaryFileStar = File
|
||||
proc c_memchr(s: pointer, c: cint, n: csize): pointer {.
|
||||
importc: "memchr", header: "<string.h>".}
|
||||
proc c_memcmp(a, b: pointer, size: csize): cint {.
|
||||
importc: "memcmp", header: "<string.h>", noSideEffect.}
|
||||
proc c_memcpy(a, b: pointer, size: csize): pointer {.
|
||||
importc: "memcpy", header: "<string.h>", discardable.}
|
||||
proc c_memmove(a, b: pointer, size: csize): pointer {.
|
||||
importc: "memmove", header: "<string.h>",discardable.}
|
||||
proc c_memset(p: pointer, value: cint, size: csize): pointer {.
|
||||
importc: "memset", header: "<string.h>", discardable.}
|
||||
proc c_strcmp(a, b: cstring): cint {.
|
||||
importc: "strcmp", header: "<string.h>", noSideEffect.}
|
||||
|
||||
type
|
||||
C_JmpBuf {.importc: "jmp_buf", header: "<setjmp.h>".} = object
|
||||
|
||||
when not defined(vm):
|
||||
var
|
||||
c_stdin {.importc: "stdin", nodecl.}: C_TextFileStar
|
||||
c_stdout {.importc: "stdout", nodecl.}: C_TextFileStar
|
||||
c_stderr {.importc: "stderr", nodecl.}: C_TextFileStar
|
||||
|
||||
# constants faked as variables:
|
||||
when not declared(SIGINT):
|
||||
when defined(windows):
|
||||
const
|
||||
SIGABRT = cint(22)
|
||||
SIGFPE = cint(8)
|
||||
SIGILL = cint(4)
|
||||
SIGINT = cint(2)
|
||||
SIGSEGV = cint(11)
|
||||
SIGTERM = cint(15)
|
||||
elif defined(macosx) or defined(linux):
|
||||
const
|
||||
SIGABRT = cint(6)
|
||||
SIGFPE = cint(8)
|
||||
SIGILL = cint(4)
|
||||
SIGINT = cint(2)
|
||||
SIGSEGV = cint(11)
|
||||
SIGTERM = cint(15)
|
||||
SIGPIPE = cint(13)
|
||||
else:
|
||||
when NoFakeVars:
|
||||
when defined(windows):
|
||||
const
|
||||
SIGABRT = cint(22)
|
||||
SIGFPE = cint(8)
|
||||
SIGILL = cint(4)
|
||||
SIGINT = cint(2)
|
||||
SIGSEGV = cint(11)
|
||||
SIGTERM = cint(15)
|
||||
elif defined(macosx) or defined(linux):
|
||||
const
|
||||
SIGABRT = cint(6)
|
||||
SIGFPE = cint(8)
|
||||
SIGILL = cint(4)
|
||||
SIGINT = cint(2)
|
||||
SIGSEGV = cint(11)
|
||||
SIGTERM = cint(15)
|
||||
SIGPIPE = cint(13)
|
||||
else:
|
||||
{.error: "SIGABRT not ported to your platform".}
|
||||
{.error: "SIGABRT not ported to your platform".}
|
||||
else:
|
||||
var
|
||||
SIGINT {.importc: "SIGINT", nodecl.}: cint
|
||||
@@ -78,10 +60,7 @@ when not declared(SIGINT):
|
||||
var SIGPIPE {.importc: "SIGPIPE", nodecl.}: cint
|
||||
|
||||
when defined(macosx):
|
||||
when NoFakeVars:
|
||||
const SIGBUS = cint(10)
|
||||
else:
|
||||
var SIGBUS {.importc: "SIGBUS", nodecl.}: cint
|
||||
const SIGBUS = cint(10)
|
||||
else:
|
||||
template SIGBUS: expr = SIGSEGV
|
||||
|
||||
@@ -103,72 +82,27 @@ else:
|
||||
proc c_setjmp(jmpb: C_JmpBuf): cint {.
|
||||
header: "<setjmp.h>", importc: "setjmp".}
|
||||
|
||||
proc c_signal(sign: cint, handler: proc (a: cint) {.noconv.}) {.
|
||||
importc: "signal", header: "<signal.h>".}
|
||||
proc c_raise(sign: cint) {.importc: "raise", header: "<signal.h>".}
|
||||
type c_sighandler_t = proc (a: cint) {.noconv.}
|
||||
proc c_signal(sign: cint, handler: proc (a: cint) {.noconv.}): c_sighandler_t {.
|
||||
importc: "signal", header: "<signal.h>", discardable.}
|
||||
|
||||
proc c_fputs(c: cstring, f: C_TextFileStar) {.importc: "fputs",
|
||||
header: "<stdio.h>".}
|
||||
proc c_fgets(c: cstring, n: int, f: C_TextFileStar): cstring {.
|
||||
importc: "fgets", header: "<stdio.h>".}
|
||||
proc c_fgetc(stream: C_TextFileStar): int {.importc: "fgetc",
|
||||
header: "<stdio.h>".}
|
||||
proc c_ungetc(c: int, f: C_TextFileStar) {.importc: "ungetc",
|
||||
header: "<stdio.h>".}
|
||||
proc c_putc(c: char, stream: C_TextFileStar) {.importc: "putc",
|
||||
header: "<stdio.h>".}
|
||||
proc c_fprintf(f: C_TextFileStar, frmt: cstring) {.
|
||||
importc: "fprintf", header: "<stdio.h>", varargs.}
|
||||
proc c_printf(frmt: cstring) {.
|
||||
importc: "printf", header: "<stdio.h>", varargs.}
|
||||
proc c_fprintf(f: File, frmt: cstring): cint {.
|
||||
importc: "fprintf", header: "<stdio.h>", varargs, discardable.}
|
||||
proc c_printf(frmt: cstring): cint {.
|
||||
importc: "printf", header: "<stdio.h>", varargs, discardable.}
|
||||
|
||||
proc c_fopen(filename, mode: cstring): C_TextFileStar {.
|
||||
importc: "fopen", header: "<stdio.h>".}
|
||||
proc c_fclose(f: C_TextFileStar) {.importc: "fclose", header: "<stdio.h>".}
|
||||
|
||||
proc c_sprintf(buf, frmt: cstring): cint {.header: "<stdio.h>",
|
||||
importc: "sprintf", varargs, noSideEffect.}
|
||||
proc c_sprintf(buf, frmt: cstring): cint {.
|
||||
importc: "sprintf", header: "<stdio.h>", varargs, noSideEffect.}
|
||||
# we use it only in a way that cannot lead to security issues
|
||||
|
||||
proc c_fread(buf: pointer, size, n: int, f: C_BinaryFileStar): int {.
|
||||
importc: "fread", header: "<stdio.h>".}
|
||||
proc c_fseek(f: C_BinaryFileStar, offset: clong, whence: int): int {.
|
||||
importc: "fseek", header: "<stdio.h>".}
|
||||
proc c_fileno(f: File): cint {.
|
||||
importc: "fileno", header: "<fcntl.h>".}
|
||||
|
||||
proc c_fwrite(buf: pointer, size, n: int, f: C_BinaryFileStar): int {.
|
||||
importc: "fwrite", header: "<stdio.h>".}
|
||||
|
||||
proc c_exit(errorcode: cint) {.importc: "exit", header: "<stdlib.h>".}
|
||||
proc c_ferror(stream: C_TextFileStar): bool {.
|
||||
importc: "ferror", header: "<stdio.h>".}
|
||||
proc c_fflush(stream: C_TextFileStar) {.importc: "fflush", header: "<stdio.h>".}
|
||||
proc c_abort() {.importc: "abort", header: "<stdlib.h>".}
|
||||
proc c_feof(stream: C_TextFileStar): bool {.
|
||||
importc: "feof", header: "<stdio.h>".}
|
||||
|
||||
proc c_malloc(size: int): pointer {.importc: "malloc", header: "<stdlib.h>".}
|
||||
proc c_free(p: pointer) {.importc: "free", header: "<stdlib.h>".}
|
||||
proc c_realloc(p: pointer, newsize: int): pointer {.
|
||||
proc c_malloc(size: csize): pointer {.
|
||||
importc: "malloc", header: "<stdlib.h>".}
|
||||
proc c_free(p: pointer) {.
|
||||
importc: "free", header: "<stdlib.h>".}
|
||||
proc c_realloc(p: pointer, newsize: csize): pointer {.
|
||||
importc: "realloc", header: "<stdlib.h>".}
|
||||
|
||||
when hostOS != "standalone":
|
||||
when not declared(errno):
|
||||
when defined(NimrodVM):
|
||||
var vmErrnoWrapper {.importc.}: ptr cint
|
||||
template errno: expr =
|
||||
bind vmErrnoWrapper
|
||||
vmErrnoWrapper[]
|
||||
else:
|
||||
var errno {.importc, header: "<errno.h>".}: cint ## error variable
|
||||
proc strerror(errnum: cint): cstring {.importc, header: "<string.h>".}
|
||||
|
||||
proc c_remove(filename: cstring): cint {.
|
||||
importc: "remove", header: "<stdio.h>".}
|
||||
proc c_rename(oldname, newname: cstring): cint {.
|
||||
importc: "rename", header: "<stdio.h>".}
|
||||
|
||||
proc c_system(cmd: cstring): cint {.importc: "system", header: "<stdlib.h>".}
|
||||
proc c_getenv(env: cstring): cstring {.importc: "getenv", header: "<stdlib.h>".}
|
||||
proc c_putenv(env: cstring): cint {.importc: "putenv", header: "<stdlib.h>".}
|
||||
|
||||
{.pop}
|
||||
|
||||
@@ -51,7 +51,6 @@ proc chckRangeF(x, a, b: float): float =
|
||||
proc chckNil(p: pointer) =
|
||||
if p == nil:
|
||||
sysFatal(ValueError, "attempt to write to a nil address")
|
||||
#c_raise(SIGSEGV)
|
||||
|
||||
proc chckObj(obj, subclass: PNimType) {.compilerproc.} =
|
||||
# checks if obj is of type subclass:
|
||||
|
||||
@@ -108,8 +108,8 @@ proc fileMatches(c, bp: cstring): bool =
|
||||
# and the character for the suffix does not exist or
|
||||
# is one of: \ / :
|
||||
# depending on the OS case does not matter!
|
||||
var blen: int = c_strlen(bp)
|
||||
var clen: int = c_strlen(c)
|
||||
var blen: int = bp.len
|
||||
var clen: int = c.len
|
||||
if blen > clen: return false
|
||||
# check for \ / :
|
||||
if clen-blen-1 >= 0 and c[clen-blen-1] notin {'\\', '/', ':'}:
|
||||
|
||||
@@ -36,7 +36,7 @@ proc copyDeepString(src: NimString): NimString {.inline.} =
|
||||
if src != nil:
|
||||
result = rawNewStringNoInit(src.len)
|
||||
result.len = src.len
|
||||
c_memcpy(result.data, src.data, src.len + 1)
|
||||
copyMem(addr(result.data), addr(src.data), src.len + 1)
|
||||
|
||||
proc genericDeepCopyAux(dest, src: pointer, mt: PNimType) =
|
||||
var
|
||||
|
||||
@@ -52,11 +52,14 @@ when defined(posix):
|
||||
#
|
||||
|
||||
# c stuff:
|
||||
var
|
||||
RTLD_NOW {.importc: "RTLD_NOW", header: "<dlfcn.h>".}: int
|
||||
when defined(linux) or defined(macosx):
|
||||
const RTLD_NOW = cint(2)
|
||||
else:
|
||||
var
|
||||
RTLD_NOW {.importc: "RTLD_NOW", header: "<dlfcn.h>".}: cint
|
||||
|
||||
proc dlclose(lib: LibHandle) {.importc, header: "<dlfcn.h>".}
|
||||
proc dlopen(path: cstring, mode: int): LibHandle {.
|
||||
proc dlopen(path: cstring, mode: cint): LibHandle {.
|
||||
importc, header: "<dlfcn.h>".}
|
||||
proc dlsym(lib: LibHandle, name: cstring): ProcAddr {.
|
||||
importc, header: "<dlfcn.h>".}
|
||||
|
||||
@@ -329,14 +329,14 @@ proc dbgStackFrame(s: cstring, start: int, currFrame: PFrame) =
|
||||
|
||||
proc readLine(f: File, line: var StaticStr): bool =
|
||||
while true:
|
||||
var c = fgetc(f)
|
||||
var c = c_fgetc(f)
|
||||
if c < 0'i32:
|
||||
if line.len > 0: break
|
||||
else: return false
|
||||
if c == 10'i32: break # LF
|
||||
if c == 13'i32: # CR
|
||||
c = fgetc(f) # is the next char LF?
|
||||
if c != 10'i32: ungetc(c, f) # no, put the character back
|
||||
c = c_fgetc(f) # is the next char LF?
|
||||
if c != 10'i32: discard c_ungetc(c, f) # no, put the character back
|
||||
break
|
||||
add line, chr(int(c))
|
||||
result = true
|
||||
|
||||
@@ -255,7 +255,7 @@ proc raiseExceptionAux(e: ref Exception) =
|
||||
add(buf, "Error: unhandled exception: ")
|
||||
if not isNil(e.msg): add(buf, e.msg)
|
||||
add(buf, " [")
|
||||
xadd(buf, e.name, c_strlen(e.name))
|
||||
xadd(buf, e.name, e.name.len)
|
||||
add(buf, "]\n")
|
||||
showErrorMessage(buf)
|
||||
quitOrDebug()
|
||||
|
||||
@@ -152,10 +152,10 @@ proc writeCell(msg: cstring, c: PCell) =
|
||||
var kind = -1
|
||||
if c.typ != nil: kind = ord(c.typ.kind)
|
||||
when leakDetector:
|
||||
c_fprintf(c_stdout, "[GC] %s: %p %d rc=%ld from %s(%ld)\n",
|
||||
c_fprintf(stdout, "[GC] %s: %p %d rc=%ld from %s(%ld)\n",
|
||||
msg, c, kind, c.refcount shr rcShift, c.filename, c.line)
|
||||
else:
|
||||
c_fprintf(c_stdout, "[GC] %s: %p %d rc=%ld; color=%ld\n",
|
||||
c_fprintf(stdout, "[GC] %s: %p %d rc=%ld; color=%ld\n",
|
||||
msg, c, kind, c.refcount shr rcShift, c.color)
|
||||
|
||||
template gcTrace(cell, state: expr): stmt {.immediate.} =
|
||||
|
||||
@@ -272,7 +272,7 @@ when false:
|
||||
proc copyDeepString(dr: var MemRegion; stack: var PointerStackChunk; src: NimString): NimString {.inline.} =
|
||||
result = rawNewStringNoInit(dr, src.len)
|
||||
result.len = src.len
|
||||
c_memcpy(result.data, src.data, src.len + 1)
|
||||
copyMem(result.data, src.data, src.len + 1)
|
||||
|
||||
proc genericDeepCopyAux(dr: var MemRegion; stack: var PointerStackChunk;
|
||||
dest, src: pointer, mt: PNimType) =
|
||||
@@ -417,15 +417,15 @@ proc asgnRefNoCycle(dest: PPointer, src: pointer) {.compilerproc, inline.} =
|
||||
dest[] = src
|
||||
|
||||
proc alloc(size: Natural): pointer =
|
||||
result = cmalloc(size)
|
||||
result = c_malloc(size)
|
||||
if result == nil: raiseOutOfMem()
|
||||
proc alloc0(size: Natural): pointer =
|
||||
result = alloc(size)
|
||||
zeroMem(result, size)
|
||||
proc realloc(p: pointer, newsize: Natural): pointer =
|
||||
result = crealloc(p, newsize)
|
||||
result = c_realloc(p, newsize)
|
||||
if result == nil: raiseOutOfMem()
|
||||
proc dealloc(p: pointer) = cfree(p)
|
||||
proc dealloc(p: pointer) = c_free(p)
|
||||
|
||||
proc alloc0(r: var MemRegion; size: Natural): pointer =
|
||||
# ignore the region. That is correct for the channels module
|
||||
@@ -435,15 +435,15 @@ proc alloc0(r: var MemRegion; size: Natural): pointer =
|
||||
proc dealloc(r: var MemRegion; p: pointer) = dealloc(p)
|
||||
|
||||
proc allocShared(size: Natural): pointer =
|
||||
result = cmalloc(size)
|
||||
result = c_malloc(size)
|
||||
if result == nil: raiseOutOfMem()
|
||||
proc allocShared0(size: Natural): pointer =
|
||||
result = alloc(size)
|
||||
zeroMem(result, size)
|
||||
proc reallocShared(p: pointer, newsize: Natural): pointer =
|
||||
result = crealloc(p, newsize)
|
||||
result = c_realloc(p, newsize)
|
||||
if result == nil: raiseOutOfMem()
|
||||
proc deallocShared(p: pointer) = cfree(p)
|
||||
proc deallocShared(p: pointer) = c_free(p)
|
||||
|
||||
when hasThreadSupport:
|
||||
proc getFreeSharedMem(): int = 0
|
||||
|
||||
@@ -300,7 +300,7 @@ elif defined(gogc):
|
||||
proc setStackBottom(theStackBottom: pointer) = discard
|
||||
|
||||
proc alloc(size: Natural): pointer =
|
||||
result = cmalloc(size)
|
||||
result = c_malloc(size)
|
||||
if result == nil: raiseOutOfMem()
|
||||
|
||||
proc alloc0(size: Natural): pointer =
|
||||
@@ -308,13 +308,13 @@ elif defined(gogc):
|
||||
zeroMem(result, size)
|
||||
|
||||
proc realloc(p: pointer, newsize: Natural): pointer =
|
||||
result = crealloc(p, newsize)
|
||||
result = c_realloc(p, newsize)
|
||||
if result == nil: raiseOutOfMem()
|
||||
|
||||
proc dealloc(p: pointer) = cfree(p)
|
||||
proc dealloc(p: pointer) = c_free(p)
|
||||
|
||||
proc allocShared(size: Natural): pointer =
|
||||
result = cmalloc(size)
|
||||
result = c_malloc(size)
|
||||
if result == nil: raiseOutOfMem()
|
||||
|
||||
proc allocShared0(size: Natural): pointer =
|
||||
@@ -322,10 +322,10 @@ elif defined(gogc):
|
||||
zeroMem(result, size)
|
||||
|
||||
proc reallocShared(p: pointer, newsize: Natural): pointer =
|
||||
result = crealloc(p, newsize)
|
||||
result = c_realloc(p, newsize)
|
||||
if result == nil: raiseOutOfMem()
|
||||
|
||||
proc deallocShared(p: pointer) = cfree(p)
|
||||
proc deallocShared(p: pointer) = c_free(p)
|
||||
|
||||
when hasThreadSupport:
|
||||
proc getFreeSharedMem(): int = discard
|
||||
@@ -389,7 +389,7 @@ elif defined(nogc) and defined(useMalloc):
|
||||
|
||||
when not defined(useNimRtl):
|
||||
proc alloc(size: Natural): pointer =
|
||||
var x = cmalloc(size + sizeof(size))
|
||||
var x = c_malloc(size + sizeof(size))
|
||||
if x == nil: raiseOutOfMem()
|
||||
|
||||
cast[ptr int](x)[] = size
|
||||
@@ -402,7 +402,7 @@ elif defined(nogc) and defined(useMalloc):
|
||||
var x = cast[pointer](cast[int](p) - sizeof(newsize))
|
||||
let oldsize = cast[ptr int](x)[]
|
||||
|
||||
x = crealloc(x, newsize + sizeof(newsize))
|
||||
x = c_realloc(x, newsize + sizeof(newsize))
|
||||
|
||||
if x == nil: raiseOutOfMem()
|
||||
|
||||
@@ -412,18 +412,18 @@ elif defined(nogc) and defined(useMalloc):
|
||||
if newsize > oldsize:
|
||||
zeroMem(cast[pointer](cast[int](result) + oldsize), newsize - oldsize)
|
||||
|
||||
proc dealloc(p: pointer) = cfree(cast[pointer](cast[int](p) - sizeof(int)))
|
||||
proc dealloc(p: pointer) = c_free(cast[pointer](cast[int](p) - sizeof(int)))
|
||||
|
||||
proc allocShared(size: Natural): pointer =
|
||||
result = cmalloc(size)
|
||||
result = c_malloc(size)
|
||||
if result == nil: raiseOutOfMem()
|
||||
proc allocShared0(size: Natural): pointer =
|
||||
result = alloc(size)
|
||||
zeroMem(result, size)
|
||||
proc reallocShared(p: pointer, newsize: Natural): pointer =
|
||||
result = crealloc(p, newsize)
|
||||
result = c_realloc(p, newsize)
|
||||
if result == nil: raiseOutOfMem()
|
||||
proc deallocShared(p: pointer) = cfree(p)
|
||||
proc deallocShared(p: pointer) = c_free(p)
|
||||
|
||||
proc GC_disable() = discard
|
||||
proc GC_enable() = discard
|
||||
|
||||
@@ -87,6 +87,8 @@ elif defined(posix):
|
||||
const MAP_ANONYMOUS = 0x1000
|
||||
elif defined(solaris):
|
||||
const MAP_ANONYMOUS = 0x100
|
||||
elif defined(linux):
|
||||
const MAP_ANONYMOUS = 0x20
|
||||
else:
|
||||
var
|
||||
MAP_ANONYMOUS {.importc: "MAP_ANONYMOUS", header: "<sys/mman.h>".}: cint
|
||||
|
||||
@@ -16,43 +16,43 @@
|
||||
# of the standard library!
|
||||
|
||||
|
||||
proc fputs(c: cstring, f: File) {.importc: "fputs", header: "<stdio.h>",
|
||||
tags: [WriteIOEffect].}
|
||||
proc fgets(c: cstring, n: int, f: File): cstring {.
|
||||
proc c_fdopen(filehandle: cint, mode: cstring): File {.
|
||||
importc: "fdopen", header: "<stdio.h>".}
|
||||
proc c_fputs(c: cstring, f: File): cint {.
|
||||
importc: "fputs", header: "<stdio.h>", tags: [WriteIOEffect].}
|
||||
proc c_fgets(c: cstring, n: cint, f: File): cstring {.
|
||||
importc: "fgets", header: "<stdio.h>", tags: [ReadIOEffect].}
|
||||
proc fgetc(stream: File): cint {.importc: "fgetc", header: "<stdio.h>",
|
||||
tags: [ReadIOEffect].}
|
||||
proc ungetc(c: cint, f: File) {.importc: "ungetc", header: "<stdio.h>",
|
||||
tags: [].}
|
||||
proc putc(c: char, stream: File) {.importc: "putc", header: "<stdio.h>",
|
||||
tags: [WriteIOEffect].}
|
||||
proc fprintf(f: File, frmt: cstring) {.importc: "fprintf",
|
||||
header: "<stdio.h>", varargs, tags: [WriteIOEffect].}
|
||||
proc strlen(c: cstring): int {.
|
||||
importc: "strlen", header: "<string.h>", tags: [].}
|
||||
proc c_fgetc(stream: File): cint {.
|
||||
importc: "fgetc", header: "<stdio.h>", tags: [ReadIOEffect].}
|
||||
proc c_ungetc(c: cint, f: File): cint {.
|
||||
importc: "ungetc", header: "<stdio.h>", tags: [].}
|
||||
proc c_putc(c: cint, stream: File): cint {.
|
||||
importc: "putc", header: "<stdio.h>", tags: [WriteIOEffect].}
|
||||
proc c_fflush(f: File): cint {.
|
||||
importc: "fflush", header: "<stdio.h>".}
|
||||
proc c_fclose(f: File): cint {.
|
||||
importc: "fclose", header: "<stdio.h>".}
|
||||
|
||||
# C routine that is used here:
|
||||
proc fread(buf: pointer, size, n: int, f: File): int {.
|
||||
proc c_fread(buf: pointer, size, n: csize, f: File): csize {.
|
||||
importc: "fread", header: "<stdio.h>", tags: [ReadIOEffect].}
|
||||
proc fseek(f: File, offset: clong, whence: int): int {.
|
||||
proc c_fseek(f: File, offset: clong, whence: cint): cint {.
|
||||
importc: "fseek", header: "<stdio.h>", tags: [].}
|
||||
proc ftell(f: File): int {.importc: "ftell", header: "<stdio.h>", tags: [].}
|
||||
proc ferror(f: File): int {.importc: "ferror", header: "<stdio.h>", tags: [].}
|
||||
proc setvbuf(stream: File, buf: pointer, typ, size: cint): cint {.
|
||||
importc, header: "<stdio.h>", tags: [].}
|
||||
proc memchr(s: pointer, c: cint, n: csize): pointer {.
|
||||
importc: "memchr", header: "<string.h>", tags: [].}
|
||||
proc memset(s: pointer, c: cint, n: csize) {.
|
||||
header: "<string.h>", importc: "memset", tags: [].}
|
||||
proc fwrite(buf: pointer, size, n: int, f: File): int {.
|
||||
importc: "fwrite", noDecl.}
|
||||
proc c_ftell(f: File): clong {.
|
||||
importc: "ftell", header: "<stdio.h>", tags: [].}
|
||||
proc c_ferror(f: File): cint {.
|
||||
importc: "ferror", header: "<stdio.h>", tags: [].}
|
||||
proc c_setvbuf(f: File, buf: pointer, mode: cint, size: csize): cint {.
|
||||
importc: "setvbuf", header: "<stdio.h>", tags: [].}
|
||||
proc c_fwrite(buf: pointer, size, n: csize, f: File): cint {.
|
||||
importc: "fwrite", header: "<stdio.h>".}
|
||||
|
||||
proc raiseEIO(msg: string) {.noinline, noreturn.} =
|
||||
sysFatal(IOError, msg)
|
||||
|
||||
{.push stackTrace:off, profiler:off.}
|
||||
proc readBuffer(f: File, buffer: pointer, len: Natural): int =
|
||||
result = fread(buffer, 1, len, f)
|
||||
result = c_fread(buffer, 1, len, f)
|
||||
|
||||
proc readBytes(f: File, a: var openArray[int8|uint8], start, len: Natural): int =
|
||||
result = readBuffer(f, addr(a[start]), len)
|
||||
@@ -62,10 +62,10 @@ proc readChars(f: File, a: var openArray[char], start, len: Natural): int =
|
||||
raiseEIO("buffer overflow: (start+len) > length of openarray buffer")
|
||||
result = readBuffer(f, addr(a[start]), len)
|
||||
|
||||
proc write(f: File, c: cstring) = fputs(c, f)
|
||||
proc write(f: File, c: cstring) = discard c_fputs(c, f)
|
||||
|
||||
proc writeBuffer(f: File, buffer: pointer, len: Natural): int =
|
||||
result = fwrite(buffer, 1, len, f)
|
||||
result = c_fwrite(buffer, 1, len, f)
|
||||
|
||||
proc writeBytes(f: File, a: openArray[int8|uint8], start, len: Natural): int =
|
||||
var x = cast[ptr array[0..1000_000_000, int8]](a)
|
||||
@@ -97,23 +97,28 @@ else:
|
||||
const
|
||||
BufSize = 4000
|
||||
|
||||
proc close*(f: File) = discard c_fclose(f)
|
||||
proc readChar*(f: File): char = result = cast[char](c_fgetc(f))
|
||||
proc flushFile*(f: File) = discard c_fflush(f)
|
||||
proc getFileHandle*(f: File): FileHandle = c_fileno(f)
|
||||
|
||||
proc readLine(f: File, line: var TaintedString): bool =
|
||||
var pos = 0
|
||||
# Use the currently reserved space for a first try
|
||||
when defined(nimscript):
|
||||
var space = 80
|
||||
var space: cint = 80
|
||||
else:
|
||||
var space = cast[PGenericSeq](line.string).space
|
||||
var space: cint = cint(cast[PGenericSeq](line.string).space)
|
||||
line.string.setLen(space)
|
||||
|
||||
while true:
|
||||
# memset to \l so that we can tell how far fgets wrote, even on EOF, where
|
||||
# fgets doesn't append an \l
|
||||
memset(addr line.string[pos], '\l'.ord, space)
|
||||
if fgets(addr line.string[pos], space, f) == nil:
|
||||
c_memset(addr line.string[pos], '\l'.ord, space)
|
||||
if c_fgets(addr line.string[pos], space, f) == nil:
|
||||
line.string.setLen(0)
|
||||
return false
|
||||
let m = memchr(addr line.string[pos], '\l'.ord, space)
|
||||
let m = c_memchr(addr line.string[pos], '\l'.ord, space)
|
||||
if m != nil:
|
||||
# \l found: Could be our own or the one by fgets, in any case, we're done
|
||||
var last = cast[ByteAddress](m) - cast[ByteAddress](addr line.string[0])
|
||||
@@ -142,23 +147,23 @@ proc readLine(f: File): TaintedString =
|
||||
|
||||
proc write(f: File, i: int) =
|
||||
when sizeof(int) == 8:
|
||||
fprintf(f, "%lld", i)
|
||||
c_fprintf(f, "%lld", i)
|
||||
else:
|
||||
fprintf(f, "%ld", i)
|
||||
c_fprintf(f, "%ld", i)
|
||||
|
||||
proc write(f: File, i: BiggestInt) =
|
||||
when sizeof(BiggestInt) == 8:
|
||||
fprintf(f, "%lld", i)
|
||||
c_fprintf(f, "%lld", i)
|
||||
else:
|
||||
fprintf(f, "%ld", i)
|
||||
c_fprintf(f, "%ld", i)
|
||||
|
||||
proc write(f: File, b: bool) =
|
||||
if b: write(f, "true")
|
||||
else: write(f, "false")
|
||||
proc write(f: File, r: float32) = fprintf(f, "%g", r)
|
||||
proc write(f: File, r: BiggestFloat) = fprintf(f, "%g", r)
|
||||
proc write(f: File, r: float32) = c_fprintf(f, "%g", r)
|
||||
proc write(f: File, r: BiggestFloat) = c_fprintf(f, "%g", r)
|
||||
|
||||
proc write(f: File, c: char) = putc(c, f)
|
||||
proc write(f: File, c: char) = discard c_putc(ord(c), f)
|
||||
proc write(f: File, a: varargs[string, `$`]) =
|
||||
for x in items(a): write(f, x)
|
||||
|
||||
@@ -178,15 +183,15 @@ proc readAllBuffer(file: File): string =
|
||||
|
||||
proc rawFileSize(file: File): int =
|
||||
# this does not raise an error opposed to `getFileSize`
|
||||
var oldPos = ftell(file)
|
||||
discard fseek(file, 0, 2) # seek the end of the file
|
||||
result = ftell(file)
|
||||
discard fseek(file, clong(oldPos), 0)
|
||||
var oldPos = c_ftell(file)
|
||||
discard c_fseek(file, 0, 2) # seek the end of the file
|
||||
result = c_ftell(file)
|
||||
discard c_fseek(file, clong(oldPos), 0)
|
||||
|
||||
proc endOfFile(f: File): bool =
|
||||
# do not blame me; blame the ANSI C standard this is so brain-damaged
|
||||
var c = fgetc(f)
|
||||
ungetc(c, f)
|
||||
var c = c_fgetc(f)
|
||||
discard c_ungetc(c, f)
|
||||
return c < 0'i32
|
||||
|
||||
proc readAllFile(file: File, len: int): string =
|
||||
@@ -197,7 +202,7 @@ proc readAllFile(file: File, len: int): string =
|
||||
if endOfFile(file):
|
||||
if bytes < len:
|
||||
result.setLen(bytes)
|
||||
elif ferror(file) != 0:
|
||||
elif c_ferror(file) != 0:
|
||||
raiseEIO("error while reading from file")
|
||||
else:
|
||||
# We read all the bytes but did not reach the EOF
|
||||
@@ -272,17 +277,34 @@ const
|
||||
# should not be translated.
|
||||
|
||||
when defined(posix) and not defined(nimscript):
|
||||
type
|
||||
Mode {.importc: "mode_t", header: "<sys/types.h>".} = cint
|
||||
when defined(linux) and defined(amd64):
|
||||
type
|
||||
Mode {.importc: "mode_t", header: "<sys/types.h>".} = cint
|
||||
|
||||
Stat {.importc: "struct stat",
|
||||
header: "<sys/stat.h>", final, pure.} = object ## struct stat
|
||||
st_mode: Mode ## Mode of file
|
||||
# fillers ensure correct size & offsets
|
||||
Stat {.importc: "struct stat",
|
||||
header: "<sys/stat.h>", final, pure.} = object ## struct stat
|
||||
filler_1: array[24, char]
|
||||
st_mode: Mode ## Mode of file
|
||||
filler_2: array[144 - 24 - 4, char]
|
||||
|
||||
proc S_ISDIR(m: Mode): bool {.importc, header: "<sys/stat.h>".}
|
||||
## Test for a directory.
|
||||
proc S_ISDIR(m: Mode): bool =
|
||||
## Test for a directory.
|
||||
(m and 0o170000) == 0o40000
|
||||
|
||||
proc fstat(a1: cint, a2: var Stat): cint {.importc, header: "<sys/stat.h>".}
|
||||
else:
|
||||
type
|
||||
Mode {.importc: "mode_t", header: "<sys/types.h>".} = cint
|
||||
|
||||
Stat {.importc: "struct stat",
|
||||
header: "<sys/stat.h>", final, pure.} = object ## struct stat
|
||||
st_mode: Mode ## Mode of file
|
||||
|
||||
proc S_ISDIR(m: Mode): bool {.importc, header: "<sys/stat.h>".}
|
||||
## Test for a directory.
|
||||
|
||||
proc c_fstat(a1: cint, a2: var Stat): cint {.
|
||||
importc: "fstat", header: "<sys/stat.h>".}
|
||||
|
||||
proc open(f: var File, filename: string,
|
||||
mode: FileMode = fmRead,
|
||||
@@ -295,45 +317,38 @@ proc open(f: var File, filename: string,
|
||||
# be opened.
|
||||
var f2 = cast[File](p)
|
||||
var res: Stat
|
||||
if fstat(getFileHandle(f2), res) >= 0'i32 and S_ISDIR(res.st_mode):
|
||||
if c_fstat(getFileHandle(f2), res) >= 0'i32 and S_ISDIR(res.st_mode):
|
||||
close(f2)
|
||||
return false
|
||||
result = true
|
||||
f = cast[File](p)
|
||||
if bufSize > 0 and bufSize <= high(cint).int:
|
||||
discard setvbuf(f, nil, IOFBF, bufSize.cint)
|
||||
discard c_setvbuf(f, nil, IOFBF, bufSize.cint)
|
||||
elif bufSize == 0:
|
||||
discard setvbuf(f, nil, IONBF, 0)
|
||||
discard c_setvbuf(f, nil, IONBF, 0)
|
||||
|
||||
proc reopen(f: File, filename: string, mode: FileMode = fmRead): bool =
|
||||
var p: pointer = freopen(filename, FormatOpen[mode], f)
|
||||
result = p != nil
|
||||
|
||||
proc fdopen(filehandle: FileHandle, mode: cstring): File {.
|
||||
importc: "fdopen", header: "<stdio.h>".}
|
||||
|
||||
proc open(f: var File, filehandle: FileHandle, mode: FileMode): bool =
|
||||
f = fdopen(filehandle, FormatOpen[mode])
|
||||
f = c_fdopen(filehandle, FormatOpen[mode])
|
||||
result = f != nil
|
||||
|
||||
proc setFilePos(f: File, pos: int64) =
|
||||
if fseek(f, clong(pos), 0) != 0:
|
||||
if c_fseek(f, clong(pos), 0) != 0:
|
||||
raiseEIO("cannot set file position")
|
||||
|
||||
proc getFilePos(f: File): int64 =
|
||||
result = ftell(f)
|
||||
result = c_ftell(f)
|
||||
if result < 0: raiseEIO("cannot retrieve file position")
|
||||
|
||||
proc getFileSize(f: File): int64 =
|
||||
var oldPos = getFilePos(f)
|
||||
discard fseek(f, 0, 2) # seek the end of the file
|
||||
discard c_fseek(f, 0, 2) # seek the end of the file
|
||||
result = getFilePos(f)
|
||||
setFilePos(f, oldPos)
|
||||
|
||||
when not declared(close):
|
||||
proc close(f: File) {.
|
||||
importc: "fclose", header: "<stdio.h>", tags: [].}
|
||||
|
||||
proc readFile(filename: string): TaintedString =
|
||||
var f: File
|
||||
if open(f, filename):
|
||||
|
||||
@@ -30,7 +30,7 @@ proc eqStrings(a, b: NimString): bool {.inline, compilerProc.} =
|
||||
if a == b: return true
|
||||
if a == nil or b == nil: return false
|
||||
return a.len == b.len and
|
||||
c_memcmp(a.data, b.data, a.len) == 0'i32
|
||||
equalMem(addr(a.data), addr(b.data), a.len)
|
||||
|
||||
when declared(allocAtomic):
|
||||
template allocStr(size: expr): expr =
|
||||
@@ -71,7 +71,7 @@ proc copyStrLast(s: NimString, start, last: int): NimString {.compilerProc.} =
|
||||
if len > 0:
|
||||
result = rawNewStringNoInit(len)
|
||||
result.len = len
|
||||
c_memcpy(result.data, addr(s.data[start]), len)
|
||||
copyMem(addr(result.data), addr(s.data[start]), len)
|
||||
result.data[len] = '\0'
|
||||
else:
|
||||
result = rawNewString(len)
|
||||
@@ -82,10 +82,10 @@ proc copyStr(s: NimString, start: int): NimString {.compilerProc.} =
|
||||
proc toNimStr(str: cstring, len: int): NimString {.compilerProc.} =
|
||||
result = rawNewStringNoInit(len)
|
||||
result.len = len
|
||||
c_memcpy(result.data, str, len + 1)
|
||||
copyMem(addr(result.data), str, len + 1)
|
||||
|
||||
proc cstrToNimstr(str: cstring): NimString {.compilerRtl.} =
|
||||
result = toNimStr(str, c_strlen(str))
|
||||
result = toNimStr(str, str.len)
|
||||
|
||||
proc copyString(src: NimString): NimString {.compilerRtl.} =
|
||||
if src != nil:
|
||||
@@ -94,7 +94,7 @@ proc copyString(src: NimString): NimString {.compilerRtl.} =
|
||||
else:
|
||||
result = rawNewStringNoInit(src.len)
|
||||
result.len = src.len
|
||||
c_memcpy(result.data, src.data, src.len + 1)
|
||||
copyMem(addr(result.data), addr(src.data), src.len + 1)
|
||||
|
||||
proc copyStringRC1(src: NimString): NimString {.compilerRtl.} =
|
||||
if src != nil:
|
||||
@@ -107,7 +107,7 @@ proc copyStringRC1(src: NimString): NimString {.compilerRtl.} =
|
||||
else:
|
||||
result = rawNewStringNoInit(src.len)
|
||||
result.len = src.len
|
||||
c_memcpy(result.data, src.data, src.len + 1)
|
||||
copyMem(addr(result.data), addr(src.data), src.len + 1)
|
||||
|
||||
|
||||
proc hashString(s: string): int {.compilerproc.} =
|
||||
@@ -177,7 +177,7 @@ proc resizeString(dest: NimString, addlen: int): NimString {.compilerRtl.} =
|
||||
# DO NOT UPDATE LEN YET: dest.len = newLen
|
||||
|
||||
proc appendString(dest, src: NimString) {.compilerproc, inline.} =
|
||||
c_memcpy(addr(dest.data[dest.len]), src.data, src.len + 1)
|
||||
copyMem(addr(dest.data[dest.len]), addr(src.data), src.len + 1)
|
||||
inc(dest.len, src.len)
|
||||
|
||||
proc appendChar(dest: NimString, c: char) {.compilerproc, inline.} =
|
||||
@@ -301,8 +301,8 @@ proc nimFloatToStr(f: float): string {.compilerproc.} =
|
||||
else:
|
||||
result = $buf
|
||||
|
||||
proc strtod(buf: cstring, endptr: ptr cstring): float64 {.importc,
|
||||
header: "<stdlib.h>", noSideEffect.}
|
||||
proc c_strtod(buf: cstring, endptr: ptr cstring): float64 {.
|
||||
importc: "strtod", header: "<stdlib.h>", noSideEffect.}
|
||||
|
||||
const
|
||||
IdentChars = {'a'..'z', 'A'..'Z', '0'..'9', '_'}
|
||||
@@ -460,7 +460,7 @@ proc nimParseBiggestFloat(s: string, number: var BiggestFloat,
|
||||
t[ti-2] = ('0'.ord + abs_exponent mod 10).char; abs_exponent = abs_exponent div 10
|
||||
t[ti-3] = ('0'.ord + abs_exponent mod 10).char
|
||||
|
||||
number = strtod(t, nil)
|
||||
number = c_strtod(t, nil)
|
||||
|
||||
proc nimInt64ToStr(x: int64): string {.compilerRtl.} =
|
||||
result = newString(sizeof(x)*4)
|
||||
|
||||
@@ -117,6 +117,11 @@ else:
|
||||
schedh = "#define _GNU_SOURCE\n#include <sched.h>"
|
||||
pthreadh = "#define _GNU_SOURCE\n#include <pthread.h>"
|
||||
|
||||
when defined(linux):
|
||||
type Time = clong
|
||||
else:
|
||||
type Time = int
|
||||
|
||||
type
|
||||
SysThread {.importc: "pthread_t", header: "<sys/types.h>",
|
||||
final, pure.} = object
|
||||
@@ -125,8 +130,8 @@ else:
|
||||
|
||||
Timespec {.importc: "struct timespec",
|
||||
header: "<time.h>", final, pure.} = object
|
||||
tv_sec: int
|
||||
tv_nsec: int
|
||||
tv_sec: Time
|
||||
tv_nsec: clong
|
||||
{.deprecated: [TSysThread: SysThread, Tpthread_attr: PThreadAttr,
|
||||
Ttimespec: Timespec].}
|
||||
|
||||
|
||||
@@ -78,11 +78,16 @@ elif defined(posixRealtime):
|
||||
|
||||
else:
|
||||
# fallback Posix implementation:
|
||||
when defined(linux):
|
||||
type Time = clong
|
||||
else:
|
||||
type Time = int
|
||||
|
||||
type
|
||||
Timeval {.importc: "struct timeval", header: "<sys/select.h>",
|
||||
final, pure.} = object ## struct timeval
|
||||
tv_sec: int ## Seconds.
|
||||
tv_usec: int ## Microseconds.
|
||||
tv_sec: Time ## Seconds.
|
||||
tv_usec: clong ## Microseconds.
|
||||
{.deprecated: [Ttimeval: Timeval].}
|
||||
proc posix_gettimeofday(tp: var Timeval, unused: pointer = nil) {.
|
||||
importc: "gettimeofday", header: "<sys/time.h>".}
|
||||
|
||||
@@ -104,12 +104,7 @@ proc newWideCString*(source: cstring, L: int): WideCString =
|
||||
proc newWideCString*(s: cstring): WideCString =
|
||||
if s.isNil: return nil
|
||||
|
||||
when not declared(c_strlen):
|
||||
proc c_strlen(a: cstring): int {.
|
||||
header: "<string.h>", noSideEffect, importc: "strlen".}
|
||||
|
||||
let L = c_strlen(s)
|
||||
result = newWideCString(s, L)
|
||||
result = newWideCString(s, s.len)
|
||||
|
||||
proc newWideCString*(s: string): WideCString =
|
||||
result = newWideCString(s, s.len)
|
||||
|
||||
Reference in New Issue
Block a user