Merge lp:~widelands-dev/widelands/windows-logging into lp:widelands

Proposed by GunChleoc
Status: Merged
Merged at revision: 8816
Proposed branch: lp:~widelands-dev/widelands/windows-logging
Merge into: lp:widelands
Diff against target: 334 lines (+88/-34)
10 files modified
src/CMakeLists.txt (+0/-2)
src/base/CMakeLists.txt (+1/-0)
src/base/log.cc (+39/-11)
src/base/log.h (+9/-0)
src/economy/test/CMakeLists.txt (+1/-0)
src/economy/test/test_road.cc (+6/-0)
src/main.cc (+6/-12)
src/notifications/test/CMakeLists.txt (+1/-0)
src/notifications/test/notifications_test.cc (+5/-0)
src/wlapplication.cc (+20/-9)
To merge this branch: bzr merge lp:~widelands-dev/widelands/windows-logging
Reviewer Review Type Date Requested Status
hessenfarmer Approve
Review via email: mp+354397@code.launchpad.net

Commit message

Write Windows log output to homedir instead of the program dir.

To post a comment you must log in.
Revision history for this message
GunChleoc (gunchleoc) wrote :

I have tested the AppVeyor release build on Windows 10. The installer had to be run as administrator when installed into C:\Program Files, the game can then be run without admin privileges. stdout.txt is written to C:\Users\<username>\.widelands

Revision history for this message
bunnybot (widelandsofficial) wrote :

Continuous integration builds have changed state:

Travis build 3908. State: passed. Details: https://travis-ci.org/widelands/widelands/builds/426088550.
Appveyor build 3706. State: success. Details: https://ci.appveyor.com/project/widelands-dev/widelands/build/_widelands_dev_widelands_windows_logging-3706.

Revision history for this message
hessenfarmer (stephan-lutz) wrote :

tested the appveyor build as well. OS win 10. Install dir on drive D:/ stdout.txt in user/.widelands.
seems to be good to go

review: Approve
Revision history for this message
GunChleoc (gunchleoc) wrote :

Thanks!

@bunnybot merge

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/CMakeLists.txt'
--- src/CMakeLists.txt 2018-07-08 10:05:27 +0000
+++ src/CMakeLists.txt 2018-09-06 15:39:53 +0000
@@ -45,7 +45,6 @@
45 ${WIN32_ICON_O}45 ${WIN32_ICON_O}
46 USES_SDL246 USES_SDL2
47 DEPENDS47 DEPENDS
48 base_log
49 base_exceptions48 base_exceptions
50 widelands_ball_of_mud49 widelands_ball_of_mud
51 build_info50 build_info
@@ -56,7 +55,6 @@
56 main.cc55 main.cc
57 USES_SDL256 USES_SDL2
58 DEPENDS57 DEPENDS
59 base_log
60 base_exceptions58 base_exceptions
61 widelands_ball_of_mud59 widelands_ball_of_mud
62 build_info60 build_info
6361
=== modified file 'src/base/CMakeLists.txt'
--- src/base/CMakeLists.txt 2017-03-04 12:37:17 +0000
+++ src/base/CMakeLists.txt 2018-09-06 15:39:53 +0000
@@ -12,6 +12,7 @@
12 DEPENDS12 DEPENDS
13 base_macros13 base_macros
14 base_exceptions14 base_exceptions
15 build_info
15)16)
1617
17wl_library(base_exceptions18wl_library(base_exceptions
1819
=== modified file 'src/base/log.cc'
--- src/base/log.cc 2018-04-07 16:59:00 +0000
+++ src/base/log.cc 2018-09-06 15:39:53 +0000
@@ -19,10 +19,12 @@
1919
20#include "base/log.h"20#include "base/log.h"
2121
22#include <cassert>
22#include <cstdarg>23#include <cstdarg>
23#include <cstdio>24#include <cstdio>
24#include <fstream>25#include <fstream>
25#include <iostream>26#include <iostream>
27#include <memory>
2628
27#include <SDL.h>29#include <SDL.h>
28#ifdef _WIN3230#ifdef _WIN32
@@ -31,6 +33,9 @@
3133
32#include "base/macros.h"34#include "base/macros.h"
33#include "base/wexception.h"35#include "base/wexception.h"
36#ifdef _WIN32
37#include "build_info.h"
38#endif
3439
35namespace {40namespace {
3641
@@ -38,7 +43,6 @@
38void sdl_logging_func(void* userdata, int, SDL_LogPriority, const char* message);43void sdl_logging_func(void* userdata, int, SDL_LogPriority, const char* message);
3944
40#ifdef _WIN3245#ifdef _WIN32
41
42std::string get_output_directory() {46std::string get_output_directory() {
43// This took inspiration from SDL 1.2 logger code.47// This took inspiration from SDL 1.2 logger code.
44#ifdef _WIN32_WCE48#ifdef _WIN32_WCE
@@ -57,12 +61,17 @@
57// This Logger emulates the SDL1.2 behavior of writing a stdout.txt.61// This Logger emulates the SDL1.2 behavior of writing a stdout.txt.
58class WindowsLogger {62class WindowsLogger {
59public:63public:
60 WindowsLogger() : stdout_filename_(get_output_directory() + "\\stdout.txt") {64 WindowsLogger(const std::string& dir) : stdout_filename_(dir + "\\stdout.txt") {
61 stdout_.open(stdout_filename_);65 stdout_.open(stdout_filename_);
62 if (!stdout_.good()) {66 if (!stdout_.good()) {
63 throw wexception("Unable to initialize logging to stdout.txt");67 throw wexception("Unable to initialize stdout logging destination: %s", stdout_filename_.c_str());
64 }68 }
65 SDL_LogSetOutputFunction(sdl_logging_func, this);69 SDL_LogSetOutputFunction(sdl_logging_func, this);
70 std::cout << "Log output will be written to: " << stdout_filename_ << std::endl;
71
72 // Repeat version info so that we'll have it available in the log file too
73 stdout_ << "This is Widelands Version " << build_id() << " (" << build_type() << ")" << std::endl;
74 stdout_.flush();
66 }75 }
6776
68 void log_cstring(const char* buffer) {77 void log_cstring(const char* buffer) {
@@ -107,23 +116,42 @@
107 static_cast<Logger*>(userdata)->log_cstring(message);116 static_cast<Logger*>(userdata)->log_cstring(message);
108}117}
109#endif118#endif
110
111} // namespace119} // namespace
112120
113// Default to stdout for logging.121// Default to stdout for logging.
114bool g_verbose = false;122bool g_verbose = false;
115123
124#ifdef _WIN32
125// Start with nullptr so that we won't initialize an empty file in the program's directory
126std::unique_ptr<WindowsLogger> logger(nullptr);
127
128// Set the logging dir to the given homedir
129bool set_logging_dir(const std::string& homedir) {
130 try {
131 logger.reset(new WindowsLogger(homedir));
132 } catch (const std::exception& e) {
133 std::cout << e.what() << std::endl;
134 return false;
135 }
136 return true;
137}
138
139// Set the logging dir to the program's dir. For running test cases where we don't have a homedir.
140void set_logging_dir() {
141 logger.reset(new WindowsLogger(get_output_directory()));
142}
143
144#else
145std::unique_ptr<Logger> logger(new Logger());
146#endif
147
116void log(const char* const fmt, ...) {148void log(const char* const fmt, ...) {
117#ifdef _WIN32149 assert(logger != nullptr);
118 static WindowsLogger logger;150
119#else
120 static Logger logger;
121#endif
122 char buffer[2048];151 char buffer[2048];
123 va_list va;152 va_list va;
124
125 va_start(va, fmt);153 va_start(va, fmt);
126 vsnprintf(buffer, sizeof(buffer), fmt, va);154 vsnprintf(buffer, sizeof(buffer), fmt, va);
127 va_end(va);155 va_end(va);
128 logger.log_cstring(buffer);156 logger->log_cstring(buffer);
129}157}
130158
=== modified file 'src/base/log.h'
--- src/base/log.h 2018-04-07 16:59:00 +0000
+++ src/base/log.h 2018-09-06 15:39:53 +0000
@@ -28,4 +28,13 @@
2828
29extern bool g_verbose;29extern bool g_verbose;
3030
31#ifdef _WIN32
32/** Set the directory that stdout.txt shall be written to.
33 * This should be the same dir where widelands writes its config file. Returns true on success.
34 */
35bool set_logging_dir(const std::string& homedir);
36// Set the directory that stdout.txt shall be written to to the directory the program is started from. Use this only for test cases.
37void set_logging_dir();
38#endif
39
31#endif // end of include guard: WL_BASE_LOG_H40#endif // end of include guard: WL_BASE_LOG_H
3241
=== modified file 'src/economy/test/CMakeLists.txt'
--- src/economy/test/CMakeLists.txt 2017-06-20 12:38:50 +0000
+++ src/economy/test/CMakeLists.txt 2018-09-06 15:39:53 +0000
@@ -4,6 +4,7 @@
4 test_road.cc4 test_road.cc
5 test_routing.cc5 test_routing.cc
6 DEPENDS6 DEPENDS
7 base_log
7 base_macros8 base_macros
8 economy9 economy
9 io_filesystem10 io_filesystem
1011
=== modified file 'src/economy/test/test_road.cc'
--- src/economy/test/test_road.cc 2018-04-07 16:59:00 +0000
+++ src/economy/test/test_road.cc 2018-09-06 15:39:53 +0000
@@ -21,6 +21,9 @@
2121
22#include <boost/test/unit_test.hpp>22#include <boost/test/unit_test.hpp>
2323
24#ifdef _WIN32
25#include "base/log.h"
26#endif
24#include "economy/flag.h"27#include "economy/flag.h"
25#include "economy/road.h"28#include "economy/road.h"
26#include "io/filesystem/layered_filesystem.h"29#include "io/filesystem/layered_filesystem.h"
@@ -51,6 +54,9 @@
51/*************************************************************************/54/*************************************************************************/
52struct WlTestFixture {55struct WlTestFixture {
53 WlTestFixture() {56 WlTestFixture() {
57#ifdef _WIN32
58 set_logging_dir();
59#endif
54 g_fs = new LayeredFileSystem();60 g_fs = new LayeredFileSystem();
55 }61 }
56 ~WlTestFixture() {62 ~WlTestFixture() {
5763
=== modified file 'src/main.cc'
--- src/main.cc 2018-04-07 16:59:00 +0000
+++ src/main.cc 2018-09-06 15:39:53 +0000
@@ -24,23 +24,17 @@
24#include <SDL_main.h>24#include <SDL_main.h>
25#include <unistd.h>25#include <unistd.h>
2626
27#include "base/log.h"
28#include "base/wexception.h"27#include "base/wexception.h"
29#include "build_info.h"28#include "build_info.h"
30#include "config.h"29#include "config.h"
31#include "wlapplication.h"30#include "wlapplication.h"
32#include "wlapplication_messages.h"31#include "wlapplication_messages.h"
3332
34using std::cout;
35using std::cerr;
36using std::endl;
37using std::flush;
38
39/**33/**
40 * Cross-platform entry point for SDL applications.34 * Cross-platform entry point for SDL applications.
41 */35 */
42int main(int argc, char* argv[]) {36int main(int argc, char* argv[]) {
43 log("This is Widelands Version %s (%s)\n", build_id().c_str(), build_type().c_str());37 std::cout << "This is Widelands Version " << build_id() << " (" << build_type() << ")" << std::endl;
4438
45 WLApplication* g_app = nullptr;39 WLApplication* g_app = nullptr;
46 try {40 try {
@@ -53,7 +47,7 @@
53 return 0;47 return 0;
54 } catch (const ParameterError& e) {48 } catch (const ParameterError& e) {
55 // handle wrong commandline parameters49 // handle wrong commandline parameters
56 cerr << endl << e.what() << endl << endl;50 std::cerr << std::endl << e.what() << std::endl << std::endl;
57 show_usage(build_id(), build_type());51 show_usage(build_id(), build_type());
58 delete g_app;52 delete g_app;
5953
@@ -61,20 +55,20 @@
61 }55 }
62#ifdef NDEBUG56#ifdef NDEBUG
63 catch (const WException& e) {57 catch (const WException& e) {
64 cerr << "\nCaught exception (of type '" << typeid(e).name()58 std::cerr << "\nCaught exception (of type '" << typeid(e).name()
65 << "') in outermost handler!\nThe exception said: " << e.what()59 << "') in outermost handler!\nThe exception said: " << e.what()
66 << "\n\nThis should not happen. Please file a bug report on version " << build_id()60 << "\n\nThis should not happen. Please file a bug report on version " << build_id()
67 << '(' << build_type() << ')' << ".\n"61 << '(' << build_type() << ')' << ".\n"
68 << "and remember to specify your operating system.\n\n" << flush;62 << "and remember to specify your operating system.\n\n" << std::flush;
69 delete g_app;63 delete g_app;
7064
71 return 1;65 return 1;
72 } catch (const std::exception& e) {66 } catch (const std::exception& e) {
73 cerr << "\nCaught exception (of type '" << typeid(e).name()67 std::cerr << "\nCaught exception (of type '" << typeid(e).name()
74 << "') in outermost handler!\nThe exception said: " << e.what()68 << "') in outermost handler!\nThe exception said: " << e.what()
75 << "\n\nThis should not happen. Please file a bug report on version " << build_id()69 << "\n\nThis should not happen. Please file a bug report on version " << build_id()
76 << '(' << build_type() << ')' << ".\n"70 << '(' << build_type() << ')' << ".\n"
77 << "and remember to specify your operating system.\n\n" << flush;71 << "and remember to specify your operating system.\n\n" << std::flush;
78 delete g_app;72 delete g_app;
7973
80 return 1;74 return 1;
8175
=== modified file 'src/notifications/test/CMakeLists.txt'
--- src/notifications/test/CMakeLists.txt 2017-06-20 12:38:50 +0000
+++ src/notifications/test/CMakeLists.txt 2018-09-06 15:39:53 +0000
@@ -2,6 +2,7 @@
2 SRCS2 SRCS
3 notifications_test.cc3 notifications_test.cc
4 DEPENDS4 DEPENDS
5 base_log
5 base_macros6 base_macros
6 notifications7 notifications
7)8)
89
=== modified file 'src/notifications/test/notifications_test.cc'
--- src/notifications/test/notifications_test.cc 2018-04-07 16:59:00 +0000
+++ src/notifications/test/notifications_test.cc 2018-09-06 15:39:53 +0000
@@ -23,6 +23,7 @@
23#define BOOST_TEST_MODULE Notifications23#define BOOST_TEST_MODULE Notifications
24#include <boost/test/unit_test.hpp>24#include <boost/test/unit_test.hpp>
2525
26#include "base/log.h"
26#include "base/macros.h"27#include "base/macros.h"
27#include "notifications/notifications.h"28#include "notifications/notifications.h"
2829
@@ -41,6 +42,10 @@
41BOOST_AUTO_TEST_SUITE(NotificationsTestSuite)42BOOST_AUTO_TEST_SUITE(NotificationsTestSuite)
4243
43BOOST_AUTO_TEST_CASE(SimpleTest) {44BOOST_AUTO_TEST_CASE(SimpleTest) {
45#ifdef _WIN32
46 set_logging_dir();
47#endif
48
44 std::vector<SimpleNote> received1;49 std::vector<SimpleNote> received1;
45 auto subscriber1 = Notifications::subscribe<SimpleNote>(50 auto subscriber1 = Notifications::subscribe<SimpleNote>(
46 [&received1](const SimpleNote& got) { received1.push_back(got); });51 [&received1](const SimpleNote& got) { received1.push_back(got); });
4752
=== modified file 'src/wlapplication.cc'
--- src/wlapplication.cc 2018-07-29 11:27:33 +0000
+++ src/wlapplication.cc 2018-09-06 15:39:53 +0000
@@ -223,21 +223,32 @@
223223
224} // namespace224} // namespace
225225
226
227// Set up the homedir. Exit 1 if the homedir is illegal or the logger couldn't be initialized for Windows.
226void WLApplication::setup_homedir() {228void WLApplication::setup_homedir() {
227 // If we don't have a home directory don't do anything229 // If we don't have a home directory, we exit with an error
228 if (homedir_.size()) {230 if (homedir_.empty()) {
229 // Assume some dir exists231 std::cout << "Unable to start Widelands, because the given homedir is empty" << std::endl;
232 delete g_fs;
233 exit(1);
234 } else {
230 try {235 try {
231 log("Set home directory: %s\n", homedir_.c_str());
232
233 std::unique_ptr<FileSystem> home(new RealFSImpl(homedir_));236 std::unique_ptr<FileSystem> home(new RealFSImpl(homedir_));
234 home->ensure_directory_exists(".");237 home->ensure_directory_exists(".");
235 g_fs->set_home_file_system(home.release());238 g_fs->set_home_file_system(home.release());
236 } catch (const std::exception& e) {239 } catch (const std::exception& e) {
237 log("Failed to add home directory: %s\n", e.what());240 std::cout << "Unable to start Widelands, because we were unable to add the home directory: " << e.what() << std::endl;
238 }241 delete g_fs;
239 } else {242 exit(1);
240 // TODO(unknown): complain243 }
244#ifdef _WIN32
245 // Initialize the logger for Windows. Exit on failure.
246 if (!set_logging_dir(homedir_)) {
247 delete g_fs;
248 exit(1);
249 }
250#endif
251 log("Set home directory: %s\n", homedir_.c_str());
241 }252 }
242}253}
243254

Subscribers

People subscribed via source and target branches

to status/vote changes: