diff --git a/nimib.nimble b/nimib.nimble index 055155cd..da1295f6 100644 --- a/nimib.nimble +++ b/nimib.nimble @@ -9,7 +9,7 @@ srcDir = "src" # Dependencies requires "nim >= 1.4.0" -requires "tempfile >= 0.1.6" +requires "fusion >= 1.2" requires "markdown >= 0.8.1" requires "mustache >= 0.2.1" requires "parsetoml >= 0.7.0" diff --git a/src/nimib/capture.nim b/src/nimib/capture.nim index f82a2978..d3906761 100644 --- a/src/nimib/capture.nim +++ b/src/nimib/capture.nim @@ -1,30 +1,29 @@ ## This submodule implements only one template to temporarily redirect and capture stdout during execution of a chunk of code. -import tempfile - -# see https://stackoverflow.com/questions/64026829/how-to-temporarily-capture-stdout -# Thanks, Clonk! - -# low level, should be Posix only but they happen to work on (my) Windows, too! -proc dup(oldfd: FileHandle): FileHandle {.importc, header: "unistd.h".} -proc dup2(oldfd: FileHandle, newfd: FileHandle): cint {.importc, header: "unistd.h".} +import fusion/ioutils +import std/tempfiles template captureStdout*(ident: untyped, body: untyped) = - ## redirect stdout to a temporary file and captures output of body in ident - let + ## redirect stdout to a temporary file and captures output of body in ident # Duplicate stdout - stdoutFileno = stdout.getFileHandle() - stdoutDupfd = dup(stdoutFileno) - # Create a new temporary file - (tmpFile, tmpFilename) = mkstemp(mode=fmWrite) - tmpFileFd: FileHandle = tmpFile.getFileHandle() - discard dup2(tmpFileFd, stdoutFileno) # writing to stdoutFileno now writes to tmpFile - - body - flushFile stdout - - # before reading tmpFile, flush and close - tmpFile.flushFile() - tmpFile.close() - ident = readFile(tmpFileName) - # Restore stdout - discard dup2(stdoutDupfd, stdoutFileno) + let stdoutFileno: FileHandle = stdout.getFileHandle() + let stdoutDupFd: FileHandle = stdoutFileno.duplicate() + + # Create a new temporary file or attempt to open it + let (tmpFile, _) = createTempFile("tmp", "") + let tmpFileFd: FileHandle = tmpFile.getFileHandle() + + # writing to stdoutFileno now writes to tmpFile + tmpFileFd.duplicateTo(stdoutFileno) + + # Execute body code + body + + # Flush stdout and tmpFile, read tmpFile from start to ident and then close tmpFile + stdout.flushFile() + tmpFile.flushFile() + tmpFile.setFilePos(0) + ident = tmpFile.readAll() + tmpFile.close() + + # Restore stdout + stdoutDupFd.duplicateTo(stdoutFileno)