1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
|
#
#
# Nim's Runtime Library
# (c) Copyright 2013 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
# This module contains headers of Ansi C procs
# and definitions of Ansi C types in Nim syntax
# All symbols are prefixed with 'c_' to avoid ambiguities
{.push hints:off, stack_trace: off, profiler: off.}
proc c_memchr*(s: pointer, c: cint, n: csize_t): pointer {.
importc: "memchr", header: "<string.h>".}
proc c_memcmp*(a, b: pointer, size: csize_t): cint {.
importc: "memcmp", header: "<string.h>", noSideEffect.}
proc c_memcpy*(a, b: pointer, size: csize_t): pointer {.
importc: "memcpy", header: "<string.h>", discardable.}
proc c_memmove*(a, b: pointer, size: csize_t): pointer {.
importc: "memmove", header: "<string.h>",discardable.}
proc c_memset*(p: pointer, value: cint, size: csize_t): pointer {.
importc: "memset", header: "<string.h>", discardable.}
proc c_strcmp*(a, b: cstring): cint {.
importc: "strcmp", header: "<string.h>", noSideEffect.}
proc c_strlen*(a: cstring): csize_t {.
importc: "strlen", header: "<string.h>", noSideEffect.}
proc c_abort*() {.
importc: "abort", header: "<stdlib.h>", noSideEffect, noreturn.}
when defined(nimBuiltinSetjmp):
type
C_JmpBuf* = array[5, pointer]
elif defined(linux) and defined(amd64):
type
C_JmpBuf* {.importc: "jmp_buf", header: "<setjmp.h>", bycopy.} = object
abi: array[200 div sizeof(clong), clong]
else:
type
C_JmpBuf* {.importc: "jmp_buf", header: "<setjmp.h>".} = object
type CSighandlerT = proc (a: cint) {.noconv.}
when defined(windows):
const
SIGABRT* = cint(22)
SIGFPE* = cint(8)
SIGILL* = cint(4)
SIGINT* = cint(2)
SIGSEGV* = cint(11)
SIGTERM = cint(15)
SIG_DFL* = cast[CSighandlerT](0)
elif defined(macosx) or defined(linux) or defined(freebsd) or
defined(openbsd) or defined(netbsd) or defined(solaris) or
defined(dragonfly) or defined(nintendoswitch) or defined(genode) or
defined(aix) or hostOS == "standalone":
const
SIGABRT* = cint(6)
SIGFPE* = cint(8)
SIGILL* = cint(4)
SIGINT* = cint(2)
SIGSEGV* = cint(11)
SIGTERM* = cint(15)
SIGPIPE* = cint(13)
SIG_DFL* = CSighandlerT(nil)
elif defined(haiku):
const
SIGABRT* = cint(6)
SIGFPE* = cint(8)
SIGILL* = cint(4)
SIGINT* = cint(2)
SIGSEGV* = cint(11)
SIGTERM* = cint(15)
SIGPIPE* = cint(7)
SIG_DFL* = CSighandlerT(nil)
else:
when defined(nimscript):
{.error: "SIGABRT not ported to your platform".}
else:
var
SIGINT* {.importc: "SIGINT", nodecl.}: cint
SIGSEGV* {.importc: "SIGSEGV", nodecl.}: cint
SIGABRT* {.importc: "SIGABRT", nodecl.}: cint
SIGFPE* {.importc: "SIGFPE", nodecl.}: cint
SIGILL* {.importc: "SIGILL", nodecl.}: cint
SIG_DFL* {.importc: "SIG_DFL", nodecl.}: CSighandlerT
when defined(macosx) or defined(linux):
var SIGPIPE* {.importc: "SIGPIPE", nodecl.}: cint
when defined(macosx):
const SIGBUS* = cint(10)
elif defined(haiku):
const SIGBUS* = cint(30)
# "nimRawSetjmp" is defined by default for certain platforms, so we need the
# "nimStdSetjmp" escape hatch with it.
when defined(nimSigSetjmp):
proc c_longjmp*(jmpb: C_JmpBuf, retval: cint) {.
header: "<setjmp.h>", importc: "siglongjmp".}
proc c_setjmp*(jmpb: C_JmpBuf): cint =
proc c_sigsetjmp(jmpb: C_JmpBuf, savemask: cint): cint {.
header: "<setjmp.h>", importc: "sigsetjmp".}
c_sigsetjmp(jmpb, 0)
elif defined(nimBuiltinSetjmp):
proc c_longjmp*(jmpb: C_JmpBuf, retval: cint) =
# Apple's Clang++ has trouble converting array names to pointers, so we need
# to be very explicit here.
proc c_builtin_longjmp(jmpb: ptr pointer, retval: cint) {.
importc: "__builtin_longjmp", nodecl.}
# The second parameter needs to be 1 and sometimes the C/C++ compiler checks it.
c_builtin_longjmp(unsafeAddr jmpb[0], 1)
proc c_setjmp*(jmpb: C_JmpBuf): cint =
proc c_builtin_setjmp(jmpb: ptr pointer): cint {.
importc: "__builtin_setjmp", nodecl.}
c_builtin_setjmp(unsafeAddr jmpb[0])
elif defined(nimRawSetjmp) and not defined(nimStdSetjmp):
when defined(windows):
# No `_longjmp()` on Windows.
proc c_longjmp*(jmpb: C_JmpBuf, retval: cint) {.
header: "<setjmp.h>", importc: "longjmp".}
when defined(vcc) or defined(clangcl):
proc c_setjmp*(jmpb: C_JmpBuf): cint {.
header: "<setjmp.h>", importc: "setjmp".}
else:
# The Windows `_setjmp()` takes two arguments, with the second being an
# undocumented buffer used by the SEH mechanism for stack unwinding.
# Mingw-w64 has been trying to get it right for years, but it's still
# prone to stack corruption during unwinding, so we disable that by setting
# it to NULL.
# More details: https://github.com/status-im/nimbus-eth2/issues/3121
when defined(nimHasStyleChecks):
{.push styleChecks: off.}
proc c_setjmp*(jmpb: C_JmpBuf): cint =
proc c_setjmp_win(jmpb: C_JmpBuf, ctx: pointer): cint {.
header: "<setjmp.h>", importc: "_setjmp".}
c_setjmp_win(jmpb, nil)
when defined(nimHasStyleChecks):
{.pop.}
else:
proc c_longjmp*(jmpb: C_JmpBuf, retval: cint) {.
header: "<setjmp.h>", importc: "_longjmp".}
proc c_setjmp*(jmpb: C_JmpBuf): cint {.
header: "<setjmp.h>", importc: "_setjmp".}
else:
proc c_longjmp*(jmpb: C_JmpBuf, retval: cint) {.
header: "<setjmp.h>", importc: "longjmp".}
proc c_setjmp*(jmpb: C_JmpBuf): cint {.
header: "<setjmp.h>", importc: "setjmp".}
proc c_signal*(sign: cint, handler: CSighandlerT): CSighandlerT {.
importc: "signal", header: "<signal.h>", discardable.}
proc c_raise*(sign: cint): cint {.importc: "raise", header: "<signal.h>".}
type
CFile {.importc: "FILE", header: "<stdio.h>",
incompleteStruct.} = object
CFilePtr* = ptr CFile ## The type representing a file handle.
# duplicated between io and ansi_c
const stdioUsesMacros = (defined(osx) or defined(freebsd) or defined(dragonfly)) and not defined(emscripten)
const stderrName = when stdioUsesMacros: "__stderrp" else: "stderr"
const stdoutName = when stdioUsesMacros: "__stdoutp" else: "stdout"
const stdinName = when stdioUsesMacros: "__stdinp" else: "stdin"
var
cstderr* {.importc: stderrName, header: "<stdio.h>".}: CFilePtr
cstdout* {.importc: stdoutName, header: "<stdio.h>".}: CFilePtr
cstdin* {.importc: stdinName, header: "<stdio.h>".}: CFilePtr
proc c_fprintf*(f: CFilePtr, 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_fputs*(c: cstring, f: CFilePtr): cint {.
importc: "fputs", header: "<stdio.h>", discardable.}
proc c_fputc*(c: char, f: CFilePtr): cint {.
importc: "fputc", header: "<stdio.h>", discardable.}
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_snprintf*(buf: cstring, n: csize_t, frmt: cstring): cint {.
importc: "snprintf", header: "<stdio.h>", varargs, noSideEffect.}
when defined(zephyr) and not defined(zephyrUseLibcMalloc):
proc c_malloc*(size: csize_t): pointer {.
importc: "k_malloc", header: "<kernel.h>".}
proc c_calloc*(nmemb, size: csize_t): pointer {.
importc: "k_calloc", header: "<kernel.h>".}
proc c_free*(p: pointer) {.
importc: "k_free", header: "<kernel.h>".}
proc c_realloc*(p: pointer, newsize: csize_t): pointer =
# Zephyr's kernel malloc doesn't support realloc
result = c_malloc(newSize)
# match the ansi c behavior
if not result.isNil():
copyMem(result, p, newSize)
c_free(p)
else:
proc c_malloc*(size: csize_t): pointer {.
importc: "malloc", header: "<stdlib.h>".}
proc c_calloc*(nmemb, size: csize_t): pointer {.
importc: "calloc", header: "<stdlib.h>".}
proc c_free*(p: pointer) {.
importc: "free", header: "<stdlib.h>".}
proc c_realloc*(p: pointer, newsize: csize_t): pointer {.
importc: "realloc", header: "<stdlib.h>".}
proc c_fwrite*(buf: pointer, size, n: csize_t, f: CFilePtr): csize_t {.
importc: "fwrite", header: "<stdio.h>".}
proc c_fflush*(f: CFilePtr): cint {.
importc: "fflush", header: "<stdio.h>".}
proc rawWriteString*(f: CFilePtr, s: cstring, length: int) {.compilerproc, nonReloadable, inline.} =
# we cannot throw an exception here!
discard c_fwrite(s, 1, cast[csize_t](length), f)
discard c_fflush(f)
proc rawWrite*(f: CFilePtr, s: cstring) {.compilerproc, nonReloadable, inline.} =
# we cannot throw an exception here!
discard c_fwrite(s, 1, c_strlen(s), f)
discard c_fflush(f)
{.pop.}
|