|
1 | 1 | ## This submodule implements only one template to temporarily redirect and capture stdout during execution of a chunk of code.
|
2 |
| -import tempfile |
3 |
| - |
4 |
| -# see https://stackoverflow.com/questions/64026829/how-to-temporarily-capture-stdout |
5 |
| -# Thanks, Clonk! |
6 |
| - |
7 |
| -# low level, should be Posix only but they happen to work on (my) Windows, too! |
8 |
| -proc dup(oldfd: FileHandle): FileHandle {.importc, header: "unistd.h".} |
9 |
| -proc dup2(oldfd: FileHandle, newfd: FileHandle): cint {.importc, header: "unistd.h".} |
| 2 | +import fusion/ioutils |
| 3 | +import std/tempfiles |
10 | 4 |
|
11 | 5 | template captureStdout*(ident: untyped, body: untyped) =
|
12 |
| - ## redirect stdout to a temporary file and captures output of body in ident |
13 |
| - let |
| 6 | + ## redirect stdout to a temporary file and captures output of body in ident |
14 | 7 | # Duplicate stdout
|
15 |
| - stdoutFileno = stdout.getFileHandle() |
16 |
| - stdoutDupfd = dup(stdoutFileno) |
17 |
| - # Create a new temporary file |
18 |
| - (tmpFile, tmpFilename) = mkstemp(mode=fmWrite) |
19 |
| - tmpFileFd: FileHandle = tmpFile.getFileHandle() |
20 |
| - discard dup2(tmpFileFd, stdoutFileno) # writing to stdoutFileno now writes to tmpFile |
21 |
| - |
22 |
| - body |
23 |
| - flushFile stdout |
24 |
| - |
25 |
| - # before reading tmpFile, flush and close |
26 |
| - tmpFile.flushFile() |
27 |
| - tmpFile.close() |
28 |
| - ident = readFile(tmpFileName) |
29 |
| - # Restore stdout |
30 |
| - discard dup2(stdoutDupfd, stdoutFileno) |
| 8 | + let stdoutFileno: FileHandle = stdout.getFileHandle() |
| 9 | + let stdoutDupFd: FileHandle = stdoutFileno.duplicate() |
| 10 | + |
| 11 | + # Create a new temporary file or attempt to open it |
| 12 | + let (tmpFile, _) = createTempFile("tmp", "") |
| 13 | + let tmpFileFd: FileHandle = tmpFile.getFileHandle() |
| 14 | + |
| 15 | + # writing to stdoutFileno now writes to tmpFile |
| 16 | + tmpFileFd.duplicateTo(stdoutFileno) |
| 17 | + |
| 18 | + # Execute body code |
| 19 | + body |
| 20 | + |
| 21 | + # Flush stdout and tmpFile, read tmpFile from start to ident and then close tmpFile |
| 22 | + stdout.flushFile() |
| 23 | + tmpFile.flushFile() |
| 24 | + tmpFile.setFilePos(0) |
| 25 | + ident = tmpFile.readAll() |
| 26 | + tmpFile.close() |
| 27 | + |
| 28 | + # Restore stdout |
| 29 | + stdoutDupFd.duplicateTo(stdoutFileno) |
0 commit comments