aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Shah <dave@ds0.me>2018-11-21 17:08:45 +0000
committerDavid Shah <dave@ds0.me>2018-11-21 17:08:45 +0000
commitb550791d9279416525d0de48d22989bcf5397535 (patch)
treefd8010fac0d112ba16f41393d01bc87d0d5a4a70
parent01377d3f8717884735113537c5502db689c88bfa (diff)
downloadnextpnr-b550791d9279416525d0de48d22989bcf5397535.tar.gz
nextpnr-b550791d9279416525d0de48d22989bcf5397535.tar.bz2
nextpnr-b550791d9279416525d0de48d22989bcf5397535.zip
Refactor log code and add log file support
Signed-off-by: David Shah <dave@ds0.me>
-rw-r--r--common/command.cc26
-rw-r--r--common/command.h1
-rw-r--r--common/log.cc113
-rw-r--r--common/log.h17
-rw-r--r--gui/basewindow.cc1
5 files changed, 52 insertions, 106 deletions
diff --git a/common/command.cc b/common/command.cc
index 5070bf9c..fd634df4 100644
--- a/common/command.cc
+++ b/common/command.cc
@@ -40,7 +40,7 @@
NEXTPNR_NAMESPACE_BEGIN
-CommandHandler::CommandHandler(int argc, char **argv) : argc(argc), argv(argv) { log_files.push_back(stdout); }
+CommandHandler::CommandHandler(int argc, char **argv) : argc(argc), argv(argv) { log_streams.clear(); }
bool CommandHandler::parseOptions()
{
@@ -64,14 +64,14 @@ bool CommandHandler::parseOptions()
bool CommandHandler::executeBeforeContext()
{
if (vm.count("help") || argc == 1) {
- std::cout << boost::filesystem::basename(argv[0])
+ std::cerr << boost::filesystem::basename(argv[0])
<< " -- Next Generation Place and Route (git sha1 " GIT_COMMIT_HASH_STR ")\n";
- std::cout << options << "\n";
+ std::cerr << options << "\n";
return argc != 1;
}
if (vm.count("version")) {
- std::cout << boost::filesystem::basename(argv[0])
+ std::cerr << boost::filesystem::basename(argv[0])
<< " -- Next Generation Place and Route (git sha1 " GIT_COMMIT_HASH_STR ")\n";
return true;
}
@@ -84,7 +84,9 @@ po::options_description CommandHandler::getGeneralOptions()
po::options_description general("General options");
general.add_options()("help,h", "show help");
general.add_options()("verbose,v", "verbose output");
- general.add_options()("quiet,q", "quiet mode, only errors displayed");
+ general.add_options()("quiet,q", "quiet mode, only errors and warnings displayed");
+ general.add_options()("log,l", po::value<std::string>(),
+ "log file, all log messages are written to this file regardless of -q");
general.add_options()("debug", "debug output");
general.add_options()("force,f", "keep running after errors");
#ifndef NO_GUI
@@ -128,7 +130,17 @@ void CommandHandler::setupContext(Context *ctx)
}
if (vm.count("quiet")) {
- log_quiet_warnings = true;
+ log_streams.push_back(std::make_pair(&std::cerr, LogLevel::WARNING));
+ } else {
+ log_streams.push_back(std::make_pair(&std::cerr, LogLevel::LOG));
+ }
+
+ if (vm.count("log")) {
+ std::string logfilename = vm["log"].as<std::string>();
+ logfile = std::ofstream(logfilename);
+ if (!logfile)
+ log_error("Failed to open log file '%s' for writing.\n", logfilename.c_str());
+ log_streams.push_back(std::make_pair(&logfile, LogLevel::LOG));
}
if (vm.count("force")) {
@@ -144,7 +156,7 @@ void CommandHandler::setupContext(Context *ctx)
int r;
do {
r = rand();
- } while(r == 0);
+ } while (r == 0);
ctx->rngseed(r);
}
diff --git a/common/command.h b/common/command.h
index 12f710f6..30e0e58b 100644
--- a/common/command.h
+++ b/common/command.h
@@ -66,6 +66,7 @@ class CommandHandler
int argc;
char **argv;
ProjectHandler project;
+ std::ofstream logfile;
};
NEXTPNR_NAMESPACE_END
diff --git a/common/log.cc b/common/log.cc
index 6b2d6065..19873148 100644
--- a/common/log.cc
+++ b/common/log.cc
@@ -32,18 +32,12 @@ NEXTPNR_NAMESPACE_BEGIN
NPNR_NORETURN void logv_error(const char *format, va_list ap) NPNR_ATTRIBUTE(noreturn);
-std::vector<FILE *> log_files;
-std::vector<std::ostream *> log_streams;
-FILE *log_errfile = NULL;
+std::vector<std::pair<std::ostream *, LogLevel>> log_streams;
log_write_type log_write_function = nullptr;
-bool log_error_stderr = false;
-bool log_cmd_error_throw = false;
-bool log_quiet_warnings = false;
std::string log_last_error;
void (*log_error_atexit)() = NULL;
-// static bool next_print_log = false;
static int log_newline_count = 0;
std::string stringf(const char *fmt, ...)
@@ -88,7 +82,7 @@ std::string vstringf(const char *fmt, va_list ap)
return string;
}
-void logv(const char *format, va_list ap)
+void logv(const char *format, va_list ap, LogLevel level = LogLevel::LOG)
{
//
// Trim newlines from the beginning
@@ -108,90 +102,50 @@ void logv(const char *format, va_list ap)
else
log_newline_count = str.size() - nnl_pos - 1;
- for (auto f : log_files)
- fputs(str.c_str(), f);
-
for (auto f : log_streams)
- *f << str;
+ if (f.second <= level)
+ *f.first << str;
if (log_write_function)
log_write_function(str);
}
-void logv_info(const char *format, va_list ap)
+void log_with_level(LogLevel level, const char *format, ...)
{
- std::string message = vstringf(format, ap);
-
- log_always("Info: %s", message.c_str());
- log_flush();
+ va_list ap;
+ va_start(ap, format);
+ logv(format, ap, level);
+ va_end(ap);
}
-void logv_warning(const char *format, va_list ap)
+void logv_prefixed(const char *prefix, const char *format, va_list ap, LogLevel level)
{
std::string message = vstringf(format, ap);
- log_always("Warning: %s", message.c_str());
+ log_with_level(level, "%s%s", prefix, message.c_str());
log_flush();
}
-void logv_warning_noprefix(const char *format, va_list ap)
-{
- std::string message = vstringf(format, ap);
-
- log_always("%s", message.c_str());
-}
-
-void logv_error(const char *format, va_list ap)
-{
-#ifdef EMSCRIPTEN
- auto backup_log_files = log_files;
-#endif
-
- if (log_errfile != NULL)
- log_files.push_back(log_errfile);
-
- if (log_error_stderr)
- for (auto &f : log_files)
- if (f == stdout)
- f = stderr;
-
- log_last_error = vstringf(format, ap);
- log_always("ERROR: %s", log_last_error.c_str());
- log_flush();
-
- if (log_error_atexit)
- log_error_atexit();
-
-#ifdef EMSCRIPTEN
- log_files = backup_log_files;
-#endif
- throw log_execution_error_exception();
-}
-
void log_always(const char *format, ...)
{
va_list ap;
va_start(ap, format);
- logv(format, ap);
+ logv(format, ap, LogLevel::ALWAYS);
va_end(ap);
}
void log(const char *format, ...)
{
- if (log_quiet_warnings)
- return;
va_list ap;
va_start(ap, format);
- logv(format, ap);
+ logv(format, ap, LogLevel::LOG);
va_end(ap);
}
void log_info(const char *format, ...)
{
- if (log_quiet_warnings)
- return;
va_list ap;
va_start(ap, format);
- logv_info(format, ap);
+ logv_prefixed("Info: ", format, ap, LogLevel::INFO);
va_end(ap);
}
@@ -199,15 +153,7 @@ void log_warning(const char *format, ...)
{
va_list ap;
va_start(ap, format);
- logv_warning(format, ap);
- va_end(ap);
-}
-
-void log_warning_noprefix(const char *format, ...)
-{
- va_list ap;
- va_start(ap, format);
- logv_warning_noprefix(format, ap);
+ logv_prefixed("Warning: ", format, ap, LogLevel::WARNING);
va_end(ap);
}
@@ -215,41 +161,26 @@ void log_error(const char *format, ...)
{
va_list ap;
va_start(ap, format);
- logv_error(format, ap);
-}
+ logv_prefixed("ERROR: ", format, ap, LogLevel::ERROR);
-void log_cmd_error(const char *format, ...)
-{
- va_list ap;
- va_start(ap, format);
-
- if (log_cmd_error_throw) {
- log_last_error = vstringf(format, ap);
- log_always("ERROR: %s", log_last_error.c_str());
- log_flush();
- throw log_cmd_error_exception();
- }
+ if (log_error_atexit)
+ log_error_atexit();
- logv_error(format, ap);
+ throw log_execution_error_exception();
}
void log_break()
{
- if (log_quiet_warnings)
- return;
if (log_newline_count < 2)
- log_always("\n");
+ log("\n");
if (log_newline_count < 2)
- log_always("\n");
+ log("\n");
}
void log_flush()
{
- for (auto f : log_files)
- fflush(f);
-
for (auto f : log_streams)
- f->flush();
+ f.first->flush();
}
NEXTPNR_NAMESPACE_END
diff --git a/common/log.h b/common/log.h
index b5fddf53..de5aa85c 100644
--- a/common/log.h
+++ b/common/log.h
@@ -42,12 +42,18 @@ struct log_execution_error_exception
{
};
-extern std::vector<FILE *> log_files;
-extern std::vector<std::ostream *> log_streams;
-extern FILE *log_errfile;
+enum class LogLevel
+{
+ LOG,
+ INFO,
+ WARNING,
+ ERROR,
+ ALWAYS
+};
+
+extern std::vector<std::pair<std::ostream *, LogLevel>> log_streams;
extern log_write_type log_write_function;
-extern bool log_quiet_warnings;
extern std::string log_last_error;
extern void (*log_error_atexit)();
@@ -59,9 +65,7 @@ void log(const char *format, ...) NPNR_ATTRIBUTE(format(printf, 1, 2));
void log_always(const char *format, ...) NPNR_ATTRIBUTE(format(printf, 1, 2));
void log_info(const char *format, ...) NPNR_ATTRIBUTE(format(printf, 1, 2));
void log_warning(const char *format, ...) NPNR_ATTRIBUTE(format(printf, 1, 2));
-void log_warning_noprefix(const char *format, ...) NPNR_ATTRIBUTE(format(printf, 1, 2));
NPNR_NORETURN void log_error(const char *format, ...) NPNR_ATTRIBUTE(format(printf, 1, 2), noreturn);
-NPNR_NORETURN void log_cmd_error(const char *format, ...) NPNR_ATTRIBUTE(format(printf, 1, 2), noreturn);
void log_break();
void log_flush();
@@ -75,7 +79,6 @@ static inline void log_assert_worker(bool cond, const char *expr, const char *fi
NEXTPNR_NAMESPACE_PREFIX log_assert_worker(_assert_expr_, #_assert_expr_, __FILE__, __LINE__)
#define log_abort() log_error("Abort in %s:%d.\n", __FILE__, __LINE__)
-#define log_ping() log("-- %s:%d %s --\n", __FILE__, __LINE__, __PRETTY_FUNCTION__)
NEXTPNR_NAMESPACE_END
diff --git a/gui/basewindow.cc b/gui/basewindow.cc
index 92812285..49c2d8d5 100644
--- a/gui/basewindow.cc
+++ b/gui/basewindow.cc
@@ -44,7 +44,6 @@ BaseMainWindow::BaseMainWindow(std::unique_ptr<Context> context, ArchArgs args,
initBasenameResource();
qRegisterMetaType<std::string>();
- log_files.clear();
log_streams.clear();
setObjectName("BaseMainWindow");