Skip to content

Commit

Permalink
Replace 'cstderr.rawWrite' with 'writeToStdErr'
Browse files Browse the repository at this point in the history
Use a procedure that is easy to replace on platforms without native
UNIX file descriptors.
  • Loading branch information
ehmry committed Mar 7, 2021
1 parent 2e8325a commit 613c535
Show file tree
Hide file tree
Showing 11 changed files with 71 additions and 63 deletions.
36 changes: 31 additions & 5 deletions lib/system.nim
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,10 @@ when notJSnotNims and not defined(nimSeqsV2):
when notJSnotNims:
include "system/hti"

proc writeToStdErr(msg: cstring, length: int)
proc writeToStdErr(msg: cstring)
proc writeToStdErr(msg: string)

type
byte* = uint8 ## This is an alias for `uint8`, that is an unsigned
## integer, 8 bits wide.
Expand Down Expand Up @@ -1226,9 +1230,9 @@ else:
template sysAssert(cond: bool, msg: string) =
when defined(useSysAssert):
if not cond:
cstderr.rawWrite "[SYSASSERT] "
cstderr.rawWrite msg
cstderr.rawWrite "\n"
writeToStdErr "[SYSASSERT] "
writeToStdErr msg
writeToStdErr "\n"
quit 1

const hasAlloc = (hostOS != "standalone" or not defined(nogc)) and not defined(nimscript)
Expand Down Expand Up @@ -1775,6 +1779,28 @@ when notJSnotNims:
import system/ansi_c
import system/memory

when defined(genode):
proc writeToStdErr(msg: cstring) =
{.emit: "Genode::error(Genode::Cstring(`msg`));".}
proc writeToStdErr(msg: cstring, length: int) =
{.emit: "Genode::error(Genode::Cstring(`msg`, `length`));".}

elif defined(windows) and defined(guiapp):
proc MessageBoxA(hWnd: pointer, lpText, lpCaption: cstring, uType: int): int32 {.
header: "<windows.h>", nodecl.}
proc writeToStdErr(msg: cstring) =
discard MessageBoxA(nil, msg, nil, 0)
proc writeToStdErr(msg: cstring, length: int) =
discard MessageBoxA(nil, msg, nil, 0)

else:
proc writeToStdErr(msg: cstring) = rawWrite(cstderr, msg)
proc writeToStdErr(msg: cstring, length: int) =
rawWriteString(cstderr, msg, length)

proc writeToStdErr(msg: string) =
# fix bug #13115: handles correctly '\0' unlike default implicit conversion to cstring
writeToStdErr(msg.cstring, msg.len)

{.push stackTrace: off.}

Expand Down Expand Up @@ -2465,8 +2491,8 @@ proc quit*(errormsg: string, errorcode = QuitFailure) {.noreturn.} =
when nimvm:
echo errormsg
else:
cstderr.rawWrite(errormsg)
cstderr.rawWrite("\n")
writeToStdErr(errormsg)
writeToStdErr("\n")
quit(errorcode)

{.pop.} # checks: off
Expand Down
10 changes: 5 additions & 5 deletions lib/system/arc.nim
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ proc nimRawDispose(p: pointer, alignment: int) {.compilerRtl.} =
cprintf("[Freed] %p\n", p -! sizeof(RefHeader))
when defined(nimOwnedEnabled):
if head(p).rc >= rcIncrement:
cstderr.rawWrite "[FATAL] dangling references exist\n"
writeToStdErr "[FATAL] dangling references exist\n"
quit 1
when defined(nimArcDebug):
# we do NOT really free the memory here in order to reliably detect use-after-frees
Expand All @@ -171,12 +171,12 @@ proc nimDestroyAndDispose(p: pointer) {.compilerRtl, raises: [].} =
if rti.destructor != nil:
cast[DestructorProc](rti.destructor)(p)
when false:
cstderr.rawWrite cast[ptr PNimTypeV2](p)[].name
cstderr.rawWrite "\n"
writeToStdErr cast[ptr PNimTypeV2](p)[].name
writeToStdErr "\n"
if d == nil:
cstderr.rawWrite "bah, nil\n"
writeToStdErr "bah, nil\n"
else:
cstderr.rawWrite "has destructor!\n"
writeToStdErr "has destructor!\n"
nimRawDispose(p, rti.align)

when defined(gcOrc):
Expand Down
34 changes: 17 additions & 17 deletions lib/system/dyncalls.nim
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ const
proc nimLoadLibraryError(path: string) =
# carefully written to avoid memory allocation:
const prefix = "could not load: "
cstderr.rawWrite(prefix)
cstderr.rawWrite(path)
writeToStdErr(prefix)
writeToStdErr(path)
when not defined(nimDebugDlOpen) and not defined(windows):
cstderr.rawWrite("\n(compile with -d:nimDebugDlOpen for more information)")
writeToStdErr("\n(compile with -d:nimDebugDlOpen for more information)")
when defined(windows):
const badExe = "\n(bad format; library may be wrong architecture)"
let loadError = GetLastError()
if loadError == ERROR_BAD_EXE_FORMAT:
cstderr.rawWrite(badExe)
writeToStdErr(badExe)
when defined(guiapp):
# Because console output is not shown in GUI apps, display the error as a
# message box instead:
Expand All @@ -46,14 +46,14 @@ proc nimLoadLibraryError(path: string) =
if loadError == ERROR_BAD_EXE_FORMAT and msgLeft >= badExe.len:
copyMem(msg[msgIdx].addr, badExe.cstring, badExe.len)
discard MessageBoxA(nil, msg[0].addr, nil, 0)
cstderr.rawWrite("\n")
writeToStdErr("\n")
quit(1)

proc procAddrError(name: cstring) {.compilerproc, nonReloadable, hcrInline.} =
# carefully written to avoid memory allocation:
cstderr.rawWrite("could not import: ")
cstderr.rawWrite(name)
cstderr.rawWrite("\n")
writeToStdErr("could not import: ")
writeToStdErr(name)
writeToStdErr("\n")
quit(1)

# this code was inspired from Lua's source code:
Expand Down Expand Up @@ -98,8 +98,8 @@ when defined(posix):
when defined(nimDebugDlOpen):
let error = dlerror()
if error != nil:
cstderr.rawWrite(error)
cstderr.rawWrite("\n")
writeToStdErr(error)
writeToStdErr("\n")

proc nimGetProcAddr(lib: LibHandle, name: cstring): ProcAddr =
result = dlsym(lib, name)
Expand Down Expand Up @@ -178,20 +178,20 @@ elif defined(genode):

elif defined(nintendoswitch) or defined(freertos):
proc nimUnloadLibrary(lib: LibHandle) =
cstderr.rawWrite("nimUnLoadLibrary not implemented")
cstderr.rawWrite("\n")
writeToStdErr("nimUnLoadLibrary not implemented")
writeToStdErr("\n")
quit(1)

proc nimLoadLibrary(path: string): LibHandle =
cstderr.rawWrite("nimLoadLibrary not implemented")
cstderr.rawWrite("\n")
writeToStdErr("nimLoadLibrary not implemented")
writeToStdErr("\n")
quit(1)


proc nimGetProcAddr(lib: LibHandle, name: cstring): ProcAddr =
cstderr.rawWrite("nimGetProAddr not implemented")
cstderr.rawWrite(name)
cstderr.rawWrite("\n")
writeToStdErr("nimGetProAddr not implemented")
writeToStdErr(name)
writeToStdErr("\n")
quit(1)

else:
Expand Down
16 changes: 0 additions & 16 deletions lib/system/excpt.nim
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,6 @@ when defined(windows):
proc GetLastError(): int32 {.header: "<windows.h>", nodecl.}
const ERROR_BAD_EXE_FORMAT = 193

when not defined(windows) or not defined(guiapp):
proc writeToStdErr(msg: cstring) = rawWrite(cstderr, msg)
proc writeToStdErr(msg: cstring, length: int) =
rawWriteString(cstderr, msg, length)
else:
proc MessageBoxA(hWnd: pointer, lpText, lpCaption: cstring, uType: int): int32 {.
header: "<windows.h>", nodecl.}
proc writeToStdErr(msg: cstring) =
discard MessageBoxA(nil, msg, nil, 0)
proc writeToStdErr(msg: cstring, length: int) =
discard MessageBoxA(nil, msg, nil, 0)

proc writeToStdErr(msg: string) {.inline.} =
# fix bug #13115: handles correctly '\0' unlike default implicit conversion to cstring
writeToStdErr(msg.cstring, msg.len)

proc showErrorMessage(data: cstring, length: int) {.gcsafe, raises: [].} =
var toWrite = true
if errorMessageWriter != nil:
Expand Down
4 changes: 1 addition & 3 deletions lib/system/fatal.nim
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ when hostOS == "standalone":
panic(arg)

elif (defined(nimQuirky) or defined(nimPanics)) and not defined(nimscript):
import ansi_c

proc name(t: typedesc): string {.magic: "TypeTrait".}

proc sysFatal(exceptn: typedesc, message, arg: string) {.inline, noreturn.} =
Expand All @@ -42,7 +40,7 @@ elif (defined(nimQuirky) or defined(nimPanics)) and not defined(nimscript):
add(buf, " [")
add(buf, name exceptn)
add(buf, "]\n")
cstderr.rawWrite buf
writeToStdErr buf
quit 1

proc sysFatal(exceptn: typedesc, message: string) {.inline, noreturn.} =
Expand Down
8 changes: 4 additions & 4 deletions lib/system/gc.nim
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,11 @@ when not defined(useNimRtl):
template gcAssert(cond: bool, msg: string) =
when defined(useGcAssert):
if not cond:
cstderr.rawWrite "[GCASSERT] "
cstderr.rawWrite msg
writeToStdErr "[GCASSERT] "
writeToStdErr msg
when defined(logGC):
cstderr.rawWrite "[GCASSERT] statistics:\L"
cstderr.rawWrite GC_getStatistics()
writeToStdErr "[GCASSERT] statistics:\L"
writeToStdErr GC_getStatistics()
GC_disable()
writeStackTrace()
#var x: ptr int
Expand Down
4 changes: 2 additions & 2 deletions lib/system/gc_common.nim
Original file line number Diff line number Diff line change
Expand Up @@ -471,13 +471,13 @@ proc nimRegisterGlobalMarker(markerProc: GlobalMarkerProc) {.compilerproc.} =
globalMarkers[globalMarkersLen] = markerProc
inc globalMarkersLen
else:
cstderr.rawWrite("[GC] cannot register global variable; too many global variables")
writeToStdErr("[GC] cannot register global variable; too many global variables")
quit 1

proc nimRegisterThreadLocalMarker(markerProc: GlobalMarkerProc) {.compilerproc.} =
if threadLocalMarkersLen <= high(threadLocalMarkers):
threadLocalMarkers[threadLocalMarkersLen] = markerProc
inc threadLocalMarkersLen
else:
cstderr.rawWrite("[GC] cannot register thread local variable; too many thread local variables")
writeToStdErr("[GC] cannot register thread local variable; too many thread local variables")
quit 1
4 changes: 2 additions & 2 deletions lib/system/gc_hooks.nim
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ proc nimRegisterGlobalMarker(markerProc: GlobalMarkerProc) {.compilerproc.} =
globalMarkers[globalMarkersLen] = markerProc
inc globalMarkersLen
else:
cstderr.rawWrite("[GC] cannot register global variable; too many global variables")
writeToStdErr("[GC] cannot register global variable; too many global variables")
quit 1

proc nimRegisterThreadLocalMarker(markerProc: GlobalMarkerProc) {.compilerproc.} =
if threadLocalMarkersLen <= high(threadLocalMarkers):
threadLocalMarkers[threadLocalMarkersLen] = markerProc
inc threadLocalMarkersLen
else:
cstderr.rawWrite("[GC] cannot register thread local variable; too many thread local variables")
writeToStdErr("[GC] cannot register thread local variable; too many thread local variables")
quit 1

proc traverseGlobals*() =
Expand Down
4 changes: 2 additions & 2 deletions lib/system/gc_ms.nim
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ when not defined(useNimRtl):
template gcAssert(cond: bool, msg: string) =
when defined(useGcAssert):
if not cond:
cstderr.rawWrite "[GCASSERT] "
cstderr.rawWrite msg
writeToStdErr "[GCASSERT] "
writeToStdErr msg
quit 1

proc cellToUsr(cell: PCell): pointer {.inline.} =
Expand Down
2 changes: 1 addition & 1 deletion lib/system/mmdisp.nim
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ else:

proc raiseOutOfMem() {.noinline.} =
if outOfMemHook != nil: outOfMemHook()
cstderr.rawWrite("out of memory\n")
writeToStdErr("out of memory")
quit(1)

when defined(boehmgc):
Expand Down
12 changes: 6 additions & 6 deletions lib/system/orc.nim
Original file line number Diff line number Diff line change
Expand Up @@ -96,16 +96,16 @@ proc free(s: Cell; desc: PNimTypeV2) {.inline.} =
cast[DisposeProc](desc.disposeImpl)(p)

when false:
cstderr.rawWrite desc.name
cstderr.rawWrite " "
writeToStdErr desc.name
writeToStdErr " "
if desc.disposeImpl == nil:
cstderr.rawWrite "lacks dispose"
writeToStdErr "lacks dispose"
if desc.traceImpl != nil:
cstderr.rawWrite ", but has trace\n"
writeToStdErr ", but has trace\n"
else:
cstderr.rawWrite ", and lacks trace\n"
writeToStdErr ", and lacks trace\n"
else:
cstderr.rawWrite "has dispose!\n"
writeToStdErr "has dispose!\n"

nimRawDispose(p, desc.align)

Expand Down

0 comments on commit 613c535

Please sign in to comment.