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)
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 ***********************************************************************/
15 #include <fc_config.h>
22 #ifdef FREECIV_HAVE_LIBREADLINE
23 #include <readline/readline.h>
27 #include "deprecations.h"
28 #include "fcbacktrace.h"
43 static bool console_show_prompt
= FALSE
;
44 static bool console_prompt_is_showing
= FALSE
;
45 static bool console_rfcstyle
= FALSE
;
46 #ifdef FREECIV_HAVE_LIBREADLINE
47 static bool readline_received_enter
= TRUE
;
49 static int con_dump(enum rfc_status rfc_status
, const char *message
, ...);
52 /************************************************************************
53 Function to handle log messages.
54 This must match the log_callback_fn typedef signature.
55 ************************************************************************/
56 static void con_handle_log(enum log_level level
, const char *message
,
59 if (LOG_ERROR
== level
) {
60 notify_conn(NULL
, NULL
, E_LOG_ERROR
, ftc_warning
, "%s", message
);
61 } else if (LOG_FATAL
>= level
) {
62 /* Make sure that message is not left to buffers when server dies */
63 conn_list_iterate(game
.est_connections
, pconn
) {
64 pconn
->send_buffer
->do_buffer_sends
= 0;
65 #ifdef USE_COMPRESSION
66 pconn
->compression
.frozen_level
= 0;
68 } conn_list_iterate_end
;
70 notify_conn(NULL
, NULL
, E_LOG_FATAL
, ftc_warning
, "%s", message
);
71 notify_conn(NULL
, NULL
, E_LOG_FATAL
, ftc_warning
,
72 _("Please report this message at %s"),
76 /* Write debug/verbose message to console only when not written to file. */
77 if (!file_too
|| level
<= LOG_NORMAL
) {
78 if (console_rfcstyle
) {
79 con_write(C_LOG_BASE
+ level
, "%s", message
);
81 con_write(C_LOG_BASE
+ level
, "%d: %s", level
, message
);
86 /************************************************************************
87 Print the prompt if it is not the last thing printed.
88 ************************************************************************/
89 static void con_update_prompt(void)
91 if (console_prompt_is_showing
|| !console_show_prompt
) {
95 #ifdef FREECIV_HAVE_LIBREADLINE
96 if (readline_received_enter
) {
97 readline_received_enter
= FALSE
;
99 rl_forced_update_display();
101 #else /* FREECIV_HAVE_LIBREADLINE */
102 con_dump(C_READY
,"> ");
104 #endif /* FREECIV_HAVE_LIBREADLINE */
106 console_prompt_is_showing
= TRUE
;
110 /************************************************************************
111 Prefix for log messages saved to file. At the moment the turn and the
112 current date and time are used.
113 ************************************************************************/
114 static const char *log_prefix(void)
116 static char buf
[128];
123 strftime(timestr
, sizeof(timestr
), "%Y/%m/%d %H:%M:%S",
124 localtime(×tamp
));
126 fc_snprintf(buf
, sizeof(buf
), "T%03d - %s", game
.info
.turn
, timestr
);
128 #else /* LOG_TIMERS */
129 fc_snprintf(buf
, sizeof(buf
), "T%03d", game
.info
.turn
);
130 #endif /* LOG_TIMERS */
134 #endif /* FREECIV_DEBUG */
136 /************************************************************************
137 Deprecation warning callback to send event to clients.
138 ************************************************************************/
139 static void depr_warn_callback(const char *msg
)
141 notify_conn(NULL
, NULL
, E_DEPRECATION_WARNING
, ftc_warning
, "%s", msg
);
144 /************************************************************************
145 Initialize logging via console.
146 ************************************************************************/
147 void con_log_init(const char *log_filename
, enum log_level level
,
148 int fatal_assertions
)
151 log_init(log_filename
, level
, con_handle_log
, log_prefix
,
154 log_init(log_filename
, level
, con_handle_log
, NULL
,
156 #endif /* FREECIV_DEBUG */
158 deprecation_warn_cb_set(depr_warn_callback
);
161 /************************************************************************
163 ************************************************************************/
164 void con_log_close(void)
171 #ifndef FREECIV_HAVE_LIBREADLINE
172 /************************************************************************
173 Write to console without line-break, don't print prompt.
174 ************************************************************************/
175 static int con_dump(enum rfc_status rfc_status
, const char *message
, ...)
177 static char buf
[MAX_LEN_CONSOLE_LINE
];
180 va_start(args
, message
);
181 fc_vsnprintf(buf
, sizeof(buf
), message
, args
);
184 if (console_prompt_is_showing
) {
187 if ((console_rfcstyle
) && (rfc_status
>= 0)) {
188 fc_printf("%.3d %s", rfc_status
, buf
);
190 fc_printf("%s", buf
);
192 console_prompt_is_showing
= FALSE
;
193 return (int) strlen(buf
);
195 #endif /* FREECIV_HAVE_LIBREADLINE */
197 /************************************************************************
198 Write to console and add line-break, and show prompt if required.
199 ************************************************************************/
200 void con_write(enum rfc_status rfc_status
, const char *message
, ...)
202 /* First buffer contains featured text tags */
203 static char buf1
[(MAX_LEN_CONSOLE_LINE
* 3) / 2];
204 static char buf2
[MAX_LEN_CONSOLE_LINE
];
207 va_start(args
, message
);
208 fc_vsnprintf(buf1
, sizeof(buf1
), message
, args
);
211 /* remove all format tags */
212 featured_text_to_plain_text(buf1
, buf2
, sizeof(buf2
), NULL
, FALSE
);
213 con_puts(rfc_status
, buf2
);
216 /************************************************************************
217 Write to console and add line-break, and show prompt if required.
218 Same as con_write, but without the format string stuff.
219 The real reason for this is because __attribute__ complained
220 with con_write(C_COMMENT,"") of "warning: zero-length format string";
221 this allows con_puts(C_COMMENT,"");
222 ************************************************************************/
223 void con_puts(enum rfc_status rfc_status
, const char *str
)
225 if (console_prompt_is_showing
) {
228 if ((console_rfcstyle
) && (rfc_status
>= 0)) {
229 fc_printf("%.3d %s\n", rfc_status
, str
);
231 fc_printf("%s\n", str
);
233 console_prompt_is_showing
= FALSE
;
237 /************************************************************************
238 Ensure timely update.
239 ************************************************************************/
245 /************************************************************************
247 ************************************************************************/
248 void con_set_style(bool i
)
250 console_rfcstyle
= i
;
251 if (console_rfcstyle
)
252 con_puts(C_OK
, _("Ok. RFC-style set."));
254 con_puts(C_OK
, _("Ok. Standard style set."));
257 /************************************************************************
259 ************************************************************************/
260 bool con_get_style(void)
262 return console_rfcstyle
;
265 /************************************************************************
266 Initialize prompt; display initial message.
267 ************************************************************************/
268 void con_prompt_init(void)
270 static bool first
= TRUE
;
273 con_puts(C_COMMENT
, "");
274 con_puts(C_COMMENT
, _("For introductory help, type 'help'."));
279 /************************************************************************
280 Make sure a prompt is printed, and re-printed after every message.
281 ************************************************************************/
282 void con_prompt_on(void)
284 console_show_prompt
= TRUE
;
288 /************************************************************************
289 Do not print a prompt after log messages.
290 ************************************************************************/
291 void con_prompt_off(void)
293 console_show_prompt
= FALSE
;
296 /************************************************************************
297 User pressed enter: will need a new prompt
298 ************************************************************************/
299 void con_prompt_enter(void)
301 console_prompt_is_showing
= FALSE
;
302 #ifdef FREECIV_HAVE_LIBREADLINE
303 readline_received_enter
= TRUE
;
307 /************************************************************************
308 Clear "user pressed enter" state (used in special cases).
309 ************************************************************************/
310 void con_prompt_enter_clear(void)
312 console_prompt_is_showing
= TRUE
;
313 #ifdef FREECIV_HAVE_LIBREADLINE
314 readline_received_enter
= FALSE
;