Fixed crash when opening file for write fails while bzip2 or xz compression is in...
[freeciv.git] / server / srv_log.c
blobe44b8cd8c25dbd171dee006347b15b5dfd0f3d51
1 /***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 #include <stdarg.h>
20 /* utility */
21 #include "astring.h"
22 #include "log.h"
23 #include "shared.h"
24 #include "support.h"
25 #include "timing.h"
27 /* common */
28 #include "ai.h"
29 #include "city.h"
30 #include "game.h"
31 #include "map.h"
32 #include "unit.h"
34 /* server */
35 #include "notify.h"
36 #include "srv_main.h"
38 /* server/advisors */
39 #include "advdata.h"
41 #include "srv_log.h"
43 static struct timer *aitimer[AIT_LAST][2];
44 static int recursion[AIT_LAST];
46 /* General AI logging functions */
48 /**************************************************************************
49 Log city messages, they will appear like this
50 2: Polish Romenna(5,35) [s1 d106 u11 g1] must have Archers ...
51 **************************************************************************/
52 void real_city_log(const char *file, const char *function, int line,
53 enum log_level level, bool notify,
54 const struct city *pcity, const char *msg, ...)
56 char buffer[500];
57 char buffer2[500];
58 va_list ap;
59 char aibuf[500] = "\0";
61 CALL_PLR_AI_FUNC(log_fragment_city, city_owner(pcity), aibuf, sizeof(aibuf), pcity);
63 fc_snprintf(buffer, sizeof(buffer), "%s %s(%d,%d) [s%d] {%s} ",
64 nation_rule_name(nation_of_city(pcity)),
65 city_name_get(pcity),
66 TILE_XY(pcity->tile), city_size_get(pcity),
67 aibuf);
69 va_start(ap, msg);
70 fc_vsnprintf(buffer2, sizeof(buffer2), msg, ap);
71 va_end(ap);
73 cat_snprintf(buffer, sizeof(buffer), "%s", buffer2);
74 if (notify) {
75 notify_conn(NULL, NULL, E_AI_DEBUG, ftc_log, "%s", buffer);
77 do_log(file, function, line, FALSE, level, "%s", buffer);
80 /**************************************************************************
81 Log unit messages, they will appear like this
82 2: Polish Archers[139] (5,35)->(0,0){0,0} stays to defend city
83 where [] is unit id, ()->() are coordinates present and goto, and
84 {,} contains bodyguard and ferryboat ids.
85 **************************************************************************/
86 void real_unit_log(const char *file, const char *function, int line,
87 enum log_level level, bool notify,
88 const struct unit *punit, const char *msg, ...)
90 char buffer[500];
91 char buffer2[500];
92 va_list ap;
93 int gx, gy;
94 char aibuf[500] = "\0";
96 CALL_PLR_AI_FUNC(log_fragment_unit, unit_owner(punit), aibuf, sizeof(aibuf), punit);
98 if (punit->goto_tile) {
99 index_to_map_pos(&gx, &gy, tile_index(punit->goto_tile));
100 } else {
101 gx = gy = -1;
104 fc_snprintf(buffer, sizeof(buffer),
105 "%s %s[%d] %s (%d,%d)->(%d,%d){%s} ",
106 nation_rule_name(nation_of_unit(punit)),
107 unit_rule_name(punit),
108 punit->id,
109 get_activity_text(punit->activity),
110 TILE_XY(unit_tile(punit)),
111 gx, gy, aibuf);
113 va_start(ap, msg);
114 fc_vsnprintf(buffer2, sizeof(buffer2), msg, ap);
115 va_end(ap);
117 cat_snprintf(buffer, sizeof(buffer), "%s", buffer2);
118 if (notify) {
119 notify_conn(NULL, NULL, E_AI_DEBUG, ftc_log, "%s", buffer);
121 do_log(file, function, line, FALSE, level, "%s", buffer);
124 /**************************************************************************
125 Measure the time between the calls. Used to see where in the AI too
126 much CPU is being used.
127 **************************************************************************/
128 void timing_log_real(enum ai_timer timer, enum ai_timer_activity activity)
130 static int turn = -1;
132 if (game.info.turn != turn) {
133 int i;
135 turn = game.info.turn;
136 for (i = 0; i < AIT_LAST; i++) {
137 timer_clear(aitimer[i][0]);
139 fc_assert(activity == TIMER_START);
142 if (activity == TIMER_START && recursion[timer] == 0) {
143 timer_start(aitimer[timer][0]);
144 timer_start(aitimer[timer][1]);
145 recursion[timer]++;
146 } else if (activity == TIMER_STOP && recursion[timer] == 1) {
147 timer_stop(aitimer[timer][0]);
148 timer_stop(aitimer[timer][1]);
149 recursion[timer]--;
153 /**************************************************************************
154 Print results
155 **************************************************************************/
156 void timing_results_real(void)
158 char buf[200];
160 #ifdef LOG_TIMERS
162 #define AILOG_OUT(text, which) \
163 fc_snprintf(buf, sizeof(buf), " %s: %g sec turn, %g sec game", text, \
164 timer_read_seconds(aitimer[which][0]), \
165 timer_read_seconds(aitimer[which][1])); \
166 log_test("%s", buf); \
167 notify_conn(NULL, NULL, E_AI_DEBUG, ftc_log, "%s", buf);
169 log_test(" --- AI timing results ---");
171 #else /* LOG_TIMERS */
173 #define AILOG_OUT(text, which) \
174 fc_snprintf(buf, sizeof(buf), " %s: %g sec turn, %g sec game", text, \
175 timer_read_seconds(aitimer[which][0]), \
176 timer_read_seconds(aitimer[which][1])); \
177 notify_conn(NULL, NULL, E_AI_DEBUG, ftc_log, "%s", buf);
179 #endif /* LOG_TIMERS */
181 notify_conn(NULL, NULL, E_AI_DEBUG, ftc_log,
182 " --- AI timing results ---");
183 AILOG_OUT("Total AI time", AIT_ALL);
184 AILOG_OUT("Movemap", AIT_MOVEMAP);
185 AILOG_OUT("Units", AIT_UNITS);
186 AILOG_OUT(" - Military", AIT_MILITARY);
187 AILOG_OUT(" - Attack", AIT_ATTACK);
188 AILOG_OUT(" - Defense", AIT_DEFENDERS);
189 AILOG_OUT(" - Ferry", AIT_FERRY);
190 AILOG_OUT(" - Rampage", AIT_RAMPAGE);
191 AILOG_OUT(" - Bodyguard", AIT_BODYGUARD);
192 AILOG_OUT(" - Recover", AIT_RECOVER);
193 AILOG_OUT(" - Caravan", AIT_CARAVAN);
194 AILOG_OUT(" - Hunter", AIT_HUNTER);
195 AILOG_OUT(" - Airlift", AIT_AIRLIFT);
196 AILOG_OUT(" - Diplomat", AIT_DIPLOMAT);
197 AILOG_OUT(" - Air", AIT_AIRUNIT);
198 AILOG_OUT(" - Explore", AIT_EXPLORER);
199 AILOG_OUT("fstk", AIT_FSTK);
200 AILOG_OUT("Settlers", AIT_SETTLERS);
201 AILOG_OUT("Workers", AIT_WORKERS);
202 AILOG_OUT("Government", AIT_GOVERNMENT);
203 AILOG_OUT("Taxes", AIT_TAXES);
204 AILOG_OUT("Cities", AIT_CITIES);
205 AILOG_OUT(" - Buildings", AIT_BUILDINGS);
206 AILOG_OUT(" - Danger", AIT_DANGER);
207 AILOG_OUT(" - Worker want", AIT_CITY_TERRAIN);
208 AILOG_OUT(" - Military want", AIT_CITY_MILITARY);
209 AILOG_OUT(" - Settler want", AIT_CITY_SETTLERS);
210 AILOG_OUT("Citizen arrange", AIT_CITIZEN_ARRANGE);
211 AILOG_OUT("Tech", AIT_TECH);
214 /**************************************************************************
215 Initialize AI timing system
216 **************************************************************************/
217 void timing_log_init(void)
219 int i;
221 for (i = 0; i < AIT_LAST; i++) {
222 aitimer[i][0] = timer_new(TIMER_CPU, TIMER_ACTIVE);
223 aitimer[i][1] = timer_new(TIMER_CPU, TIMER_ACTIVE);
224 recursion[i] = 0;
228 /**************************************************************************
229 Free AI timing system resources
230 **************************************************************************/
231 void timing_log_free(void)
233 int i;
235 for (i = 0; i < AIT_LAST; i++) {
236 timer_destroy(aitimer[i][0]);
237 timer_destroy(aitimer[i][1]);