diff options
author | Rupert Swarbrick <rswarbrick@gmail.com> | 2020-03-27 10:25:20 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-27 03:25:20 -0700 |
commit | bf296ca0643fa445b83d8bd45eefa3fca02d9921 (patch) | |
tree | 69222028c8870f885e7207959cafa8a83e4cbfce /riscv/log_file.h | |
parent | 66b44bfbedda562a32e4a2cd0716afbf731b69cd (diff) | |
download | spike-bf296ca0643fa445b83d8bd45eefa3fca02d9921.zip spike-bf296ca0643fa445b83d8bd45eefa3fca02d9921.tar.gz spike-bf296ca0643fa445b83d8bd45eefa3fca02d9921.tar.bz2 |
Write execution logs to a named log file (#409)
This patch adds a --log argument to spike. If not given, the behaviour
is unchanged: messages logging execution of instructions and (if
commit logging is enabled) commits go to stderr.
If --log=P is given, Spike now writes these messages to a log file at
the path P. This is nice, because they are no longer tangled up with
other errors and warnings.
The code is mostly plumbing: passing a FILE* object through to the
functions that were using stderr. I've written a simple "log_file_t"
class, which opens a log file if necessary and yields it or stderr.
Diffstat (limited to 'riscv/log_file.h')
-rw-r--r-- | riscv/log_file.h | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/riscv/log_file.h b/riscv/log_file.h new file mode 100644 index 0000000..d039859 --- /dev/null +++ b/riscv/log_file.h @@ -0,0 +1,37 @@ +// See LICENSE for license details. +#ifndef _RISCV_LOGFILE_H +#define _RISCV_LOGFILE_H + +#include <stdio.h> +#include <memory> +#include <sstream> +#include <stdexcept> + +// Header-only class wrapping a log file. When constructed with an +// actual path, it opens the named file for writing. When constructed +// with the null path, it wraps stderr. +class log_file_t +{ +public: + log_file_t(const char *path) + : wrapped_file (nullptr, &fclose) + { + if (!path) + return; + + wrapped_file.reset(fopen(path, "w")); + if (! wrapped_file) { + std::ostringstream oss; + oss << "Failed to open log file at `" << path << "': " + << strerror (errno); + throw std::runtime_error(oss.str()); + } + } + + FILE *get() { return wrapped_file ? wrapped_file.get() : stderr; } + +private: + std::unique_ptr<FILE, decltype(&fclose)> wrapped_file; +}; + +#endif |