widelands-dev team mailing list archive
-
widelands-dev team
-
Mailing list archive
-
Message #08085
[Merge] lp:~widelands-dev/widelands/sdl2_logging into lp:widelands
SirVer has proposed merging lp:~widelands-dev/widelands/sdl2_logging into lp:widelands.
Commit message:
- Removes --logfile command line flag. Use redirects instead.
- Adds a SDL2 aware logger that replicates writing a stdout.txt on windows (untested).
I think this a reasonable first-snow, minimal invasive fix to bring back a similar logging behavior that we had with SDL 1.2. I am unsure if always writing a logfile is such a great idea performance wise, but it never came up as a bottleneck, so it will probably be fine.
Requested reviews:
Tino (tino79)
Widelands Developers (widelands-dev)
Related bugs:
Bug #1386741 in widelands: "Fix logging"
https://bugs.launchpad.net/widelands/+bug/1386741
For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/sdl2_logging/+merge/302866
Tino, could you test this branch (and fix the compile errors I most certainly made?) - I still do not have access to a windows machine for building.
--
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/sdl2_logging into lp:widelands.
=== modified file 'src/base/log.cc'
--- src/base/log.cc 2016-08-04 15:49:05 +0000
+++ src/base/log.cc 2016-08-13 12:29:25 +0000
@@ -18,24 +18,110 @@
*/
#include "base/log.h"
+#include "base/macros.h"
+
+#include <SDL2/SDL.h>
#include <cstdarg>
#include <cstdio>
+#include <fstream>
#include <iostream>
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+namespace {
+
+// Forward declaration to work around cyclic dependency.
+void sdl_logging_func(void* userdata, int, SDL_LogPriority, const char* message);
+
+#ifdef _WIN32
+
+string get_output_directory() {
+ // This took inspiration from SDL 1.2 logger code.
+#ifdef _WIN32_WCE
+ wchar_t path[MAX_PATH];
+#else
+ char path[MAX_PATH];
+#endif
+ const auto pathlen = GetModuleFileName(NULL, path, MAX_PATH);
+ while (pathlen > 0 && path[pathlen] != '\\') {
+ --pathlen;
+ }
+ path[pathlen] = '\0';
+ return path;
+}
+
+// This Logger emulates the SDL1.2 behavior of writing a stdout.txt.
+class WindowsLogger {
+public:
+ WindowsLogger() : stdout_filename_(get_output_directory() + "\\stdout.txt") {
+ stdout_.open(stdout_filename_);
+ if (!stdout_.good()) {
+ throw wexception("Unable to initialize logging to stdout.txt");
+ }
+ SDL_LogSetOutputFunction(sdl_logging_func, this);
+ }
+
+ void log_cstring(const char* buffer) {
+ stdout_ << buffer;
+ stdout_.flush();
+ }
+
+private:
+ const string stdout_filename_;
+ ofstream stdout_;
+
+ DISALLOW_COPY_AND_ASSIGN(WindowsLogger);
+};
+
+void sdl_logging_func(void* userdata,
+ int /* category */,
+ SDL_LogPriority /* priority */,
+ const char* message) {
+ static_cast<WindowsLogger*>(userdata)->log_cstring(message);
+}
+#else // _WIN32
+
+class Logger {
+public:
+ Logger() {
+ SDL_LogSetOutputFunction(sdl_logging_func, this);
+ }
+
+ void log_cstring(const char* buffer) {
+ std::cout << buffer;
+ std::cout.flush();
+ }
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(Logger);
+};
+
+void sdl_logging_func(void* userdata,
+ int /* category */,
+ SDL_LogPriority /* priority */,
+ const char* message) {
+ static_cast<Logger*>(userdata)->log_cstring(message);
+}
+#endif
+
+} // namespace
// Default to stdout for logging.
-std::ostream& wout = std::cout;
-
bool g_verbose = false;
void log(const char* const fmt, ...) {
+#ifdef _WIN32
+ static WindowsLogger logger;
+#else
+ static Logger logger;
+#endif
char buffer[2048];
va_list va;
va_start(va, fmt);
vsnprintf(buffer, sizeof(buffer), fmt, va);
va_end(va);
-
- wout << buffer;
- wout.flush();
+ logger.log_cstring(buffer);
}
=== modified file 'src/base/log.h'
--- src/base/log.h 2016-08-04 15:49:05 +0000
+++ src/base/log.h 2016-08-13 12:29:25 +0000
@@ -46,9 +46,7 @@
#define PRIXS PRIS_PREFIX "X"
#define PRIoS PRIS_PREFIX "o"
-// Print a formatted log messages to wout.
-// wout is either std::cout or specified logfile.
-extern std::ostream& wout;
+// Print a formatted log messages to stdout on most systems and 'stdout.txt' on windows.
void log(const char*, ...) PRINTF_FORMAT(1, 2);
extern bool g_verbose;
=== modified file 'src/wlapplication.cc'
--- src/wlapplication.cc 2016-08-04 15:49:05 +0000
+++ src/wlapplication.cc 2016-08-13 12:29:25 +0000
@@ -832,18 +832,6 @@
* true otherwise.
*/
void WLApplication::handle_commandline_parameters() {
- if (commandline_.count("logfile")) {
- logfile_ = commandline_["logfile"];
- std::cerr << "Redirecting log target to: " << logfile_ << std::endl;
- if (logfile_.size() != 0) {
- // TODO(unknown): (very small) memory leak of 1 ofstream;
- // swaw the buffers (internally) of the file and wout
- std::ofstream* widelands_out = new std::ofstream(logfile_.c_str());
- std::streambuf* logbuf = widelands_out->rdbuf();
- wout.rdbuf(logbuf);
- }
- commandline_.erase("logfile");
- }
if (commandline_.count("nosound")) {
g_sound_handler.nosound_ = true;
commandline_.erase("nosound");
=== modified file 'src/wlapplication.h'
--- src/wlapplication.h 2016-08-04 15:49:05 +0000
+++ src/wlapplication.h 2016-08-13 12:29:25 +0000
@@ -229,9 +229,6 @@
/// --scenario or --loadgame.
std::string script_to_run_;
- // Log all output to this file if set, otherwise use cout
- std::string logfile_;
-
GameType game_type_;
/// True if left and right mouse button should be swapped
=== modified file 'src/wlapplication_messages.cc'
--- src/wlapplication_messages.cc 2016-08-04 15:49:05 +0000
+++ src/wlapplication_messages.cc 2016-08-13 12:29:25 +0000
@@ -44,9 +44,6 @@
std::cout << _("Options:") << endl << endl;
std::cout << _(" --<config-entry-name>=value overwrites any config file setting") << endl
<< endl
- << _(" --logfile=FILENAME Log output to file FILENAME instead of \n"
- " terminal output")
- << endl
<< _(" --datadir=DIRNAME Use specified directory for the widelands\n"
" data files")
<< endl