diff --git a/src/klayout_main/klayout_main/klayout.cc b/src/klayout_main/klayout_main/klayout.cc index f813f404b..f8ea6924d 100644 --- a/src/klayout_main/klayout_main/klayout.cc +++ b/src/klayout_main/klayout_main/klayout.cc @@ -87,6 +87,8 @@ FORCE_LINK_GSI_QTUITOOLS #include #include +#include +#include #include int klayout_main (int &argc, char **argv); @@ -202,6 +204,74 @@ void custom_message_handler(QtMsgType type, const char *msg) static int klayout_main_cont (int &argc, char **argv); +namespace { + +class LogFileWriter + : public tl::Channel +{ +public: + static std::unique_ptr m_os; + + LogFileWriter (int min_verbosity, const std::string &prefix) + : m_min_verbosity (min_verbosity), m_prefix (prefix), m_new_line (true) + { } + + static bool open (const std::string &path) + { + m_os.reset (new std::ofstream (path)); + return m_os->good (); + } + + void puts (const char *s) + { + if (m_os && tl::verbosity () >= m_min_verbosity) { + m_os->write (s, strlen (s)); + } + } + + void endl () + { + puts ("\n"); + m_new_line = true; + } + + void end () + { + if (m_os && tl::verbosity () >= m_min_verbosity) { + m_os->flush (); + } + } + + void begin () + { + if (m_new_line) { + puts (m_prefix.c_str ()); + m_new_line = false; + } + } + + void yield () { } + +private: + int m_min_verbosity; + std::string m_prefix; + bool m_new_line; +}; + +std::unique_ptr LogFileWriter::m_os; + +} + +static void set_log_file (const std::string &log_file) +{ + if (LogFileWriter::open (log_file)) { + tl::info.add (new LogFileWriter (0, std::string ()), true); + tl::log.add (new LogFileWriter (10, std::string ()), true); + tl::warn.add (new LogFileWriter (0, std::string ("Warning: ")), true); + tl::error.add (new LogFileWriter (0, std::string ("ERROR: ")), true); + } +} + /** * @brief The basic entry point * Note that by definition, klayout_main receives arguments in UTF-8 @@ -229,7 +299,7 @@ klayout_main (int &argc, char **argv) about_text += prg_about_text; lay::Version::set_about_text (about_text.c_str ()); - // Capture the shortcut command line arguments and the verbosity settings + // Capture the shortcut command line arguments, log file and the verbosity settings // for early errors and warnings for (int i = 1; i < argc; ++i) { @@ -244,6 +314,10 @@ klayout_main (int &argc, char **argv) tl::info << lay::ApplicationBase::usage () << tl::noendl; return 0; + } else if (argv [i] == std::string ("-k") && (i + 1) < argc) { + + set_log_file (argv [++i]); + } else if (argv [i] == std::string ("-d") && (i + 1) < argc) { int v = 0; diff --git a/src/lay/lay/layApplication.cc b/src/lay/lay/layApplication.cc index e7c54f768..12db519c5 100644 --- a/src/lay/lay/layApplication.cc +++ b/src/lay/lay/layApplication.cc @@ -317,6 +317,11 @@ ApplicationBase::parse_cmd (int &argc, char **argv) } tl::verbosity (v); + } else if (a == "-k" && (i + 1) < argc) { + + // ignored (handled earlier) + ++i; + } else if (a == "-l" && (i + 1) < argc) { m_layer_props_file = args [++i]; @@ -1055,6 +1060,7 @@ ApplicationBase::usage () r += tl::to_string (QObject::tr (" -i Disable undo buffering (less memory requirements)")) + "\n"; r += tl::to_string (QObject::tr (" -ni Enable undo buffering (default, overrides previous -i option)")) + "\n"; r += tl::to_string (QObject::tr (" -j Add the given path to the macro project paths")) + "\n"; + r += tl::to_string (QObject::tr (" -k Write log to the given file plus stdout/stderr")) + "\n"; r += tl::to_string (QObject::tr (" -l Use layer properties file")) + "\n"; r += tl::to_string (QObject::tr (" -lx With -l: add other layers as well")) + "\n"; r += tl::to_string (QObject::tr (" -lf With -l: use the lyp file as it is (no expansion to multiple layouts)")) + "\n";