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
1=== modified file 'src/CMakeLists.txt'
2--- src/CMakeLists.txt 2018-07-08 10:05:27 +0000
3+++ src/CMakeLists.txt 2018-09-06 15:39:53 +0000
4@@ -45,7 +45,6 @@
5 ${WIN32_ICON_O}
6 USES_SDL2
7 DEPENDS
8- base_log
9 base_exceptions
10 widelands_ball_of_mud
11 build_info
12@@ -56,7 +55,6 @@
13 main.cc
14 USES_SDL2
15 DEPENDS
16- base_log
17 base_exceptions
18 widelands_ball_of_mud
19 build_info
20
21=== modified file 'src/base/CMakeLists.txt'
22--- src/base/CMakeLists.txt 2017-03-04 12:37:17 +0000
23+++ src/base/CMakeLists.txt 2018-09-06 15:39:53 +0000
24@@ -12,6 +12,7 @@
25 DEPENDS
26 base_macros
27 base_exceptions
28+ build_info
29 )
30
31 wl_library(base_exceptions
32
33=== modified file 'src/base/log.cc'
34--- src/base/log.cc 2018-04-07 16:59:00 +0000
35+++ src/base/log.cc 2018-09-06 15:39:53 +0000
36@@ -19,10 +19,12 @@
37
38 #include "base/log.h"
39
40+#include <cassert>
41 #include <cstdarg>
42 #include <cstdio>
43 #include <fstream>
44 #include <iostream>
45+#include <memory>
46
47 #include <SDL.h>
48 #ifdef _WIN32
49@@ -31,6 +33,9 @@
50
51 #include "base/macros.h"
52 #include "base/wexception.h"
53+#ifdef _WIN32
54+#include "build_info.h"
55+#endif
56
57 namespace {
58
59@@ -38,7 +43,6 @@
60 void sdl_logging_func(void* userdata, int, SDL_LogPriority, const char* message);
61
62 #ifdef _WIN32
63-
64 std::string get_output_directory() {
65 // This took inspiration from SDL 1.2 logger code.
66 #ifdef _WIN32_WCE
67@@ -57,12 +61,17 @@
68 // This Logger emulates the SDL1.2 behavior of writing a stdout.txt.
69 class WindowsLogger {
70 public:
71- WindowsLogger() : stdout_filename_(get_output_directory() + "\\stdout.txt") {
72+ WindowsLogger(const std::string& dir) : stdout_filename_(dir + "\\stdout.txt") {
73 stdout_.open(stdout_filename_);
74 if (!stdout_.good()) {
75- throw wexception("Unable to initialize logging to stdout.txt");
76+ throw wexception("Unable to initialize stdout logging destination: %s", stdout_filename_.c_str());
77 }
78 SDL_LogSetOutputFunction(sdl_logging_func, this);
79+ std::cout << "Log output will be written to: " << stdout_filename_ << std::endl;
80+
81+ // Repeat version info so that we'll have it available in the log file too
82+ stdout_ << "This is Widelands Version " << build_id() << " (" << build_type() << ")" << std::endl;
83+ stdout_.flush();
84 }
85
86 void log_cstring(const char* buffer) {
87@@ -107,23 +116,42 @@
88 static_cast<Logger*>(userdata)->log_cstring(message);
89 }
90 #endif
91-
92 } // namespace
93
94 // Default to stdout for logging.
95 bool g_verbose = false;
96
97+#ifdef _WIN32
98+// Start with nullptr so that we won't initialize an empty file in the program's directory
99+std::unique_ptr<WindowsLogger> logger(nullptr);
100+
101+// Set the logging dir to the given homedir
102+bool set_logging_dir(const std::string& homedir) {
103+ try {
104+ logger.reset(new WindowsLogger(homedir));
105+ } catch (const std::exception& e) {
106+ std::cout << e.what() << std::endl;
107+ return false;
108+ }
109+ return true;
110+}
111+
112+// Set the logging dir to the program's dir. For running test cases where we don't have a homedir.
113+void set_logging_dir() {
114+ logger.reset(new WindowsLogger(get_output_directory()));
115+}
116+
117+#else
118+std::unique_ptr<Logger> logger(new Logger());
119+#endif
120+
121 void log(const char* const fmt, ...) {
122-#ifdef _WIN32
123- static WindowsLogger logger;
124-#else
125- static Logger logger;
126-#endif
127+ assert(logger != nullptr);
128+
129 char buffer[2048];
130 va_list va;
131-
132 va_start(va, fmt);
133 vsnprintf(buffer, sizeof(buffer), fmt, va);
134 va_end(va);
135- logger.log_cstring(buffer);
136+ logger->log_cstring(buffer);
137 }
138
139=== modified file 'src/base/log.h'
140--- src/base/log.h 2018-04-07 16:59:00 +0000
141+++ src/base/log.h 2018-09-06 15:39:53 +0000
142@@ -28,4 +28,13 @@
143
144 extern bool g_verbose;
145
146+#ifdef _WIN32
147+/** Set the directory that stdout.txt shall be written to.
148+ * This should be the same dir where widelands writes its config file. Returns true on success.
149+ */
150+bool set_logging_dir(const std::string& homedir);
151+// Set the directory that stdout.txt shall be written to to the directory the program is started from. Use this only for test cases.
152+void set_logging_dir();
153+#endif
154+
155 #endif // end of include guard: WL_BASE_LOG_H
156
157=== modified file 'src/economy/test/CMakeLists.txt'
158--- src/economy/test/CMakeLists.txt 2017-06-20 12:38:50 +0000
159+++ src/economy/test/CMakeLists.txt 2018-09-06 15:39:53 +0000
160@@ -4,6 +4,7 @@
161 test_road.cc
162 test_routing.cc
163 DEPENDS
164+ base_log
165 base_macros
166 economy
167 io_filesystem
168
169=== modified file 'src/economy/test/test_road.cc'
170--- src/economy/test/test_road.cc 2018-04-07 16:59:00 +0000
171+++ src/economy/test/test_road.cc 2018-09-06 15:39:53 +0000
172@@ -21,6 +21,9 @@
173
174 #include <boost/test/unit_test.hpp>
175
176+#ifdef _WIN32
177+#include "base/log.h"
178+#endif
179 #include "economy/flag.h"
180 #include "economy/road.h"
181 #include "io/filesystem/layered_filesystem.h"
182@@ -51,6 +54,9 @@
183 /*************************************************************************/
184 struct WlTestFixture {
185 WlTestFixture() {
186+#ifdef _WIN32
187+ set_logging_dir();
188+#endif
189 g_fs = new LayeredFileSystem();
190 }
191 ~WlTestFixture() {
192
193=== modified file 'src/main.cc'
194--- src/main.cc 2018-04-07 16:59:00 +0000
195+++ src/main.cc 2018-09-06 15:39:53 +0000
196@@ -24,23 +24,17 @@
197 #include <SDL_main.h>
198 #include <unistd.h>
199
200-#include "base/log.h"
201 #include "base/wexception.h"
202 #include "build_info.h"
203 #include "config.h"
204 #include "wlapplication.h"
205 #include "wlapplication_messages.h"
206
207-using std::cout;
208-using std::cerr;
209-using std::endl;
210-using std::flush;
211-
212 /**
213 * Cross-platform entry point for SDL applications.
214 */
215 int main(int argc, char* argv[]) {
216- log("This is Widelands Version %s (%s)\n", build_id().c_str(), build_type().c_str());
217+ std::cout << "This is Widelands Version " << build_id() << " (" << build_type() << ")" << std::endl;
218
219 WLApplication* g_app = nullptr;
220 try {
221@@ -53,7 +47,7 @@
222 return 0;
223 } catch (const ParameterError& e) {
224 // handle wrong commandline parameters
225- cerr << endl << e.what() << endl << endl;
226+ std::cerr << std::endl << e.what() << std::endl << std::endl;
227 show_usage(build_id(), build_type());
228 delete g_app;
229
230@@ -61,20 +55,20 @@
231 }
232 #ifdef NDEBUG
233 catch (const WException& e) {
234- cerr << "\nCaught exception (of type '" << typeid(e).name()
235+ std::cerr << "\nCaught exception (of type '" << typeid(e).name()
236 << "') in outermost handler!\nThe exception said: " << e.what()
237 << "\n\nThis should not happen. Please file a bug report on version " << build_id()
238 << '(' << build_type() << ')' << ".\n"
239- << "and remember to specify your operating system.\n\n" << flush;
240+ << "and remember to specify your operating system.\n\n" << std::flush;
241 delete g_app;
242
243 return 1;
244 } catch (const std::exception& e) {
245- cerr << "\nCaught exception (of type '" << typeid(e).name()
246+ std::cerr << "\nCaught exception (of type '" << typeid(e).name()
247 << "') in outermost handler!\nThe exception said: " << e.what()
248 << "\n\nThis should not happen. Please file a bug report on version " << build_id()
249 << '(' << build_type() << ')' << ".\n"
250- << "and remember to specify your operating system.\n\n" << flush;
251+ << "and remember to specify your operating system.\n\n" << std::flush;
252 delete g_app;
253
254 return 1;
255
256=== modified file 'src/notifications/test/CMakeLists.txt'
257--- src/notifications/test/CMakeLists.txt 2017-06-20 12:38:50 +0000
258+++ src/notifications/test/CMakeLists.txt 2018-09-06 15:39:53 +0000
259@@ -2,6 +2,7 @@
260 SRCS
261 notifications_test.cc
262 DEPENDS
263+ base_log
264 base_macros
265 notifications
266 )
267
268=== modified file 'src/notifications/test/notifications_test.cc'
269--- src/notifications/test/notifications_test.cc 2018-04-07 16:59:00 +0000
270+++ src/notifications/test/notifications_test.cc 2018-09-06 15:39:53 +0000
271@@ -23,6 +23,7 @@
272 #define BOOST_TEST_MODULE Notifications
273 #include <boost/test/unit_test.hpp>
274
275+#include "base/log.h"
276 #include "base/macros.h"
277 #include "notifications/notifications.h"
278
279@@ -41,6 +42,10 @@
280 BOOST_AUTO_TEST_SUITE(NotificationsTestSuite)
281
282 BOOST_AUTO_TEST_CASE(SimpleTest) {
283+#ifdef _WIN32
284+ set_logging_dir();
285+#endif
286+
287 std::vector<SimpleNote> received1;
288 auto subscriber1 = Notifications::subscribe<SimpleNote>(
289 [&received1](const SimpleNote& got) { received1.push_back(got); });
290
291=== modified file 'src/wlapplication.cc'
292--- src/wlapplication.cc 2018-07-29 11:27:33 +0000
293+++ src/wlapplication.cc 2018-09-06 15:39:53 +0000
294@@ -223,21 +223,32 @@
295
296 } // namespace
297
298+
299+// Set up the homedir. Exit 1 if the homedir is illegal or the logger couldn't be initialized for Windows.
300 void WLApplication::setup_homedir() {
301- // If we don't have a home directory don't do anything
302- if (homedir_.size()) {
303- // Assume some dir exists
304+ // If we don't have a home directory, we exit with an error
305+ if (homedir_.empty()) {
306+ std::cout << "Unable to start Widelands, because the given homedir is empty" << std::endl;
307+ delete g_fs;
308+ exit(1);
309+ } else {
310 try {
311- log("Set home directory: %s\n", homedir_.c_str());
312-
313 std::unique_ptr<FileSystem> home(new RealFSImpl(homedir_));
314 home->ensure_directory_exists(".");
315 g_fs->set_home_file_system(home.release());
316 } catch (const std::exception& e) {
317- log("Failed to add home directory: %s\n", e.what());
318- }
319- } else {
320- // TODO(unknown): complain
321+ std::cout << "Unable to start Widelands, because we were unable to add the home directory: " << e.what() << std::endl;
322+ delete g_fs;
323+ exit(1);
324+ }
325+#ifdef _WIN32
326+ // Initialize the logger for Windows. Exit on failure.
327+ if (!set_logging_dir(homedir_)) {
328+ delete g_fs;
329+ exit(1);
330+ }
331+#endif
332+ log("Set home directory: %s\n", homedir_.c_str());
333 }
334 }
335

Subscribers

People subscribed via source and target branches

to status/vote changes: