Freeciv-3.3: /fast/freeciv/nightly/main/client/gui-gtk-4.0/luaconsole.c Source File

Freeciv-3.3

Loading...
Searching...
No Matches
luaconsole.c
Go to the documentation of this file.
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.
7
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*****************************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <gdk/gdkkeysyms.h>
19
20/* utility */
21#include "fcintl.h"
22#include "log.h"
23#include "shared.h"
24
25/* common */
26#include "featured_text.h"
27#include "game.h"
28
29/* client */
30#include "options.h"
31
32/* client/gui-gtk-4.0 */
33#include "chatline.h"
34#include "gui_main.h"
35#include "gui_stuff.h"
36
37/* client/luascript */
38#include "script_client.h"
39
40#include "luaconsole.h"
41
42 enum luaconsole_res {
43 LUACONSOLE_RES_OPEN
44};
45
46#define MAX_LUACONSOLE_HISTORY 20
47
48struct luaconsole_data {
49 struct gui_dialog *shell;
50 GtkTextBuffer *message_buffer;
51 GtkTextView *message_area;
52 GtkWidget *entry;
53
54 struct genlist *history_list;
55 int history_pos;
56};
57
58 static struct luaconsole_data *luaconsole = NULL;
59
60
61static struct luaconsole_data *luaconsole_dialog_get(void);
62static void luaconsole_dialog_create(struct luaconsole_data *pdialog);
63static void luaconsole_dialog_refresh(struct luaconsole_data *pdialog);
64static void luaconsole_dialog_destroy(struct luaconsole_data *pdialog);
65
66static void luaconsole_dialog_area_resize(GtkWidget *widget, int width, int height,
67 gpointer data);
68static void luaconsole_dialog_scroll_to_bottom(void);
69
70static void luaconsole_input_return(GtkEntry *w, gpointer data);
71static gboolean luaconsole_input_handler(GtkWidget *w, GdkEvent *ev);
72
73static void luaconsole_response_callback(struct gui_dialog *pgui_dialog,
74 int response, gpointer data);
75static void luaconsole_load_file_popup(void);
76static void luaconsole_load_file_callback(GtkWidget *widget, gint response,
77 gpointer data);
78
79/*************************************************************************/
82 void luaconsole_dialog_init(void)
83{
84 fc_assert_ret(luaconsole == NULL);
85
86 /* Create a container for the dialog. */
87 luaconsole = fc_calloc(1, sizeof(*luaconsole));
88 luaconsole->message_buffer = gtk_text_buffer_new(NULL);
89 luaconsole->shell = NULL;
90
91 luaconsole->history_list = genlist_new();
92 luaconsole->history_pos = -1;
93
94 luaconsole_welcome_message();
95}
96
97/*************************************************************************/
100 void luaconsole_dialog_done(void)
101{
102 if (luaconsole != NULL) {
103 if (luaconsole->history_list) {
104 genlist_destroy(luaconsole->history_list);
105 }
106
107 luaconsole_dialog_popdown();
108 free(luaconsole);
109
110 luaconsole = NULL;
111 }
112}
113
114/*************************************************************************/
117 static struct luaconsole_data *luaconsole_dialog_get(void)
118{
119 return luaconsole;
120}
121
122/*************************************************************************/
125 void luaconsole_dialog_popup(bool raise)
126{
127 struct luaconsole_data *pdialog = luaconsole_dialog_get();
128
129 fc_assert_ret(pdialog);
130 if (pdialog->shell == NULL) {
131 luaconsole_dialog_create(pdialog);
132 }
133
134 gui_dialog_present(pdialog->shell);
135 if (raise) {
136 gui_dialog_raise(pdialog->shell);
137 }
138}
139
140/*************************************************************************/
143 void luaconsole_dialog_popdown(void)
144{
145 struct luaconsole_data *pdialog = luaconsole_dialog_get();
146
147 fc_assert_ret(pdialog);
148 if (pdialog->shell == NULL) {
149 luaconsole_dialog_destroy(pdialog);
150 }
151}
152
153/*************************************************************************/
156 bool luaconsole_dialog_is_open(void)
157{
158 struct luaconsole_data *pdialog = luaconsole_dialog_get();
159
160 fc_assert_ret_val(pdialog, FALSE);
161
162 return (NULL != pdialog->shell);
163}
164
165/*************************************************************************/
168 void real_luaconsole_dialog_update(void)
169{
170 struct luaconsole_data *pdialog = luaconsole_dialog_get();
171
172 fc_assert_ret(pdialog);
173
174 if (NULL != pdialog->shell) {
175 luaconsole_dialog_refresh(pdialog);
176 }
177}
178
179/*************************************************************************/
182 static void luaconsole_dialog_create(struct luaconsole_data *pdialog)
183{
184 GtkWidget *entry, *vgrid, *sw, *text, *notebook;
185 int grid_row = 0;
186
187 fc_assert_ret(NULL != pdialog);
188
189 if (GUI_GTK_OPTION(message_chat_location) == GUI_GTK_MSGCHAT_SPLIT) {
190 notebook = right_notebook;
191 } else {
192 notebook = bottom_notebook;
193 }
194
195 gui_dialog_new(&pdialog->shell, GTK_NOTEBOOK(notebook), pdialog, TRUE);
196 gui_dialog_set_title(pdialog->shell, _("Client Lua Console"));
197
198 vgrid = gtk_grid_new();
199 gtk_orientable_set_orientation(GTK_ORIENTABLE(vgrid),
200 GTK_ORIENTATION_VERTICAL);
201 gui_dialog_add_content_widget(pdialog->shell, vgrid);
202
203 sw = gtk_scrolled_window_new();
204 gtk_scrolled_window_set_has_frame(GTK_SCROLLED_WINDOW(sw), TRUE);
205 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
206 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
207 gtk_grid_attach(GTK_GRID(vgrid), sw, 0, grid_row++, 1, 1);
208
209 text = gtk_text_view_new_with_buffer(pdialog->message_buffer);
210 gtk_widget_set_hexpand(text, TRUE);
211 gtk_widget_set_vexpand(text, TRUE);
212 set_message_buffer_view_link_handlers(text);
213 gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE);
214 gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(sw), text);
215 g_signal_connect(text, "resize",
216 G_CALLBACK(luaconsole_dialog_area_resize), NULL);
217
218 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_WORD);
219 gtk_widget_realize(text);
220 gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text), 5);
221
222 pdialog->message_area = GTK_TEXT_VIEW(text);
223 g_signal_connect(text, "destroy", G_CALLBACK(widget_destroyed),
224 &pdialog->message_area);
225
226 /* The lua console input line. */
227 entry = gtk_entry_new();
228 gtk_widget_set_margin_bottom(entry, 2);
229 gtk_widget_set_margin_end(entry, 2);
230 gtk_widget_set_margin_start(entry, 2);
231 gtk_widget_set_margin_top(entry, 2);
232 gtk_grid_attach(GTK_GRID(vgrid), entry, 0, grid_row++, 1, 1);
233 g_signal_connect(entry, "activate", G_CALLBACK(luaconsole_input_return),
234 NULL);
235 g_signal_connect(entry, "key_press_event",
236 G_CALLBACK(luaconsole_input_handler), NULL);
237 pdialog->entry = entry;
238 g_signal_connect(entry, "destroy", G_CALLBACK(widget_destroyed),
239 &pdialog->entry);
240
241 /* Load lua script command button. */
242 gui_dialog_add_button(pdialog->shell, "window-close", _("_Close"),
243 GTK_RESPONSE_CLOSE);
244
245 gui_dialog_add_button(pdialog->shell, "document-open",
246 _("Load Lua Script"), LUACONSOLE_RES_OPEN);
247 gui_dialog_response_set_callback(pdialog->shell,
248 luaconsole_response_callback);
249
250 luaconsole_dialog_refresh(pdialog);
251 gui_dialog_show_all(pdialog->shell);
252}
253
254/*************************************************************************/
257 static void luaconsole_input_return(GtkEntry *w, gpointer data)
258{
259 const char *theinput;
260 struct luaconsole_data *pdialog = luaconsole_dialog_get();
261 GtkEntryBuffer *buffer;
262
263 fc_assert_ret(pdialog);
264 fc_assert_ret(pdialog->history_list);
265
266 buffer = gtk_entry_get_buffer(w);
267 theinput = gtk_entry_buffer_get_text(buffer);
268
269 if (*theinput) {
270 luaconsole_printf(ftc_luaconsole_input, "(input)> %s", theinput);
271 script_client_do_string(theinput);
272
273 if (genlist_size(pdialog->history_list) >= MAX_LUACONSOLE_HISTORY) {
274 void *history_data;
275
276 history_data = genlist_get(pdialog->history_list, -1);
277 genlist_remove(pdialog->history_list, history_data);
278 free(history_data);
279 }
280
281 genlist_prepend(pdialog->history_list, fc_strdup(theinput));
282 pdialog->history_pos = -1;
283 }
284
285 gtk_entry_buffer_set_text(buffer, "", -1);
286}
287
288/*************************************************************************/
291 static void luaconsole_response_callback(struct gui_dialog *pgui_dialog,
292 int response, gpointer data)
293{
294 switch (response) {
295 case LUACONSOLE_RES_OPEN:
296 break;
297 default:
298 gui_dialog_destroy(pgui_dialog);
299 return;
300 }
301
302 switch (response) {
303 case LUACONSOLE_RES_OPEN:
304 luaconsole_load_file_popup();
305 break;
306 }
307}
308
309/*************************************************************************/
312 static void luaconsole_load_file_popup(void)
313{
314 GtkWidget *filesel;
315
316 /* Create the selector */
317 filesel = gtk_file_chooser_dialog_new("Load Lua file", GTK_WINDOW(toplevel),
318 GTK_FILE_CHOOSER_ACTION_OPEN,
319 _("_Cancel"), GTK_RESPONSE_CANCEL,
320 _("_Open"), GTK_RESPONSE_OK,
321 NULL);
322 setup_dialog(filesel, toplevel);
323
324 g_signal_connect(filesel, "response",
325 G_CALLBACK(luaconsole_load_file_callback), NULL);
326
327 /* Display that dialog */
328 gtk_window_present(GTK_WINDOW(filesel));
329}
330
331/*************************************************************************/
334 static void luaconsole_load_file_callback(GtkWidget *dlg, gint response,
335 gpointer data)
336{
337 if (response == GTK_RESPONSE_OK) {
338 GFile *file = gtk_file_chooser_get_file(GTK_FILE_CHOOSER(dlg));
339
340 if (file != NULL) {
341 gchar *filename = g_file_get_parse_name(file);
342
343 if (NULL != filename) {
344 luaconsole_printf(ftc_luaconsole_input, "(file)> %s", filename);
345 script_client_do_file(filename);
346 g_free(filename);
347 }
348
349 g_object_unref(file);
350 }
351 }
352
353 gtk_window_destroy(GTK_WINDOW(dlg));
354}
355
356/*************************************************************************/
359 static gboolean luaconsole_input_handler(GtkWidget *w, GdkEvent *ev)
360{
361 struct luaconsole_data *pdialog = luaconsole_dialog_get();
362 guint keyval;
363 GtkEntryBuffer *buffer = gtk_entry_get_buffer(GTK_ENTRY(w));
364
365 fc_assert_ret_val(pdialog, FALSE);
366 fc_assert_ret_val(pdialog->history_list, FALSE);
367
368 keyval = gdk_key_event_get_keyval(ev);
369 switch (keyval) {
370 case GDK_KEY_Up:
371 if (pdialog->history_pos < genlist_size(pdialog->history_list) - 1) {
372 gtk_entry_buffer_set_text(buffer, genlist_get(pdialog->history_list,
373 ++pdialog->history_pos), -1);
374 gtk_editable_set_position(GTK_EDITABLE(w), -1);
375 }
376 return TRUE;
377
378 case GDK_KEY_Down:
379 if (pdialog->history_pos >= 0) {
380 pdialog->history_pos--;
381 }
382
383 if (pdialog->history_pos >= 0) {
384 gtk_entry_buffer_set_text(buffer, genlist_get(pdialog->history_list,
385 pdialog->history_pos), -1);
386 } else {
387 gtk_entry_buffer_set_text(buffer, "", -1);
388 }
389 gtk_editable_set_position(GTK_EDITABLE(w), -1);
390 return TRUE;
391
392 default:
393 break;
394 }
395
396 return FALSE;
397}
398
399/*************************************************************************/
404 static void luaconsole_dialog_area_resize(GtkWidget *widget, int width, int height,
405 gpointer data)
406{
407 static int old_width = 0, old_height = 0;
408
409 if (width != old_width
410 || height != old_height) {
411 luaconsole_dialog_scroll_to_bottom();
412 old_width = width;
413 old_height = height;
414 }
415}
416
417/*************************************************************************/
423 static void luaconsole_dialog_scroll_to_bottom(void)
424{
425 struct luaconsole_data *pdialog = luaconsole_dialog_get();
426
427 fc_assert_ret(pdialog);
428
429 if (pdialog->shell) {
430 GtkTextIter end;
431
432 fc_assert_ret(NULL != pdialog->message_buffer);
433 fc_assert_ret(NULL != pdialog->message_area);
434
435 gtk_text_buffer_get_end_iter(pdialog->message_buffer, &end);
436 gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(pdialog->message_area),
437 &end, 0.0, TRUE, 1.0, 0.0);
438 }
439}
440
441/*************************************************************************/
444 static void luaconsole_dialog_refresh(struct luaconsole_data *pdialog)
445{
446 fc_assert_ret(NULL != pdialog);
447}
448
449/*************************************************************************/
452 static void luaconsole_dialog_destroy(struct luaconsole_data *pdialog)
453{
454 fc_assert_ret(NULL != pdialog);
455
456 if (pdialog->shell) {
457 gui_dialog_destroy(pdialog->shell);
458 fc_assert(NULL == pdialog->shell);
459 }
460 fc_assert(NULL == pdialog->message_area);
461 fc_assert(NULL == pdialog->entry);
462}
463
464/*************************************************************************/
468 void real_luaconsole_append(const char *astring,
469 const struct text_tag_list *tags)
470{
471 GtkTextBuffer *buf;
472 GtkTextIter iter;
473 GtkTextMark *mark;
474 ft_offset_t text_start_offset;
475 struct luaconsole_data *pdialog = luaconsole_dialog_get();
476
477 fc_assert_ret(pdialog);
478
479 buf = pdialog->message_buffer;
480 gtk_text_buffer_get_end_iter(buf, &iter);
481 gtk_text_buffer_insert(buf, &iter, "\n", -1);
482 mark = gtk_text_buffer_create_mark(buf, NULL, &iter, TRUE);
483
484 if (GUI_GTK_OPTION(show_chat_message_time)) {
485 char timebuf[64];
486 time_t now;
487 struct tm now_tm;
488
489 now = time(NULL);
490 fc_localtime(&now, &now_tm);
491 strftime(timebuf, sizeof(timebuf), "[%H:%M:%S] ", &now_tm);
492 gtk_text_buffer_insert(buf, &iter, timebuf, -1);
493 }
494
495 text_start_offset = gtk_text_iter_get_offset(&iter);
496 gtk_text_buffer_insert(buf, &iter, astring, -1);
497 text_tag_list_iterate(tags, ptag) {
498 apply_text_tag(ptag, buf, text_start_offset, astring);
499 } text_tag_list_iterate_end;
500
501 if (pdialog->message_area) {
502 scroll_if_necessary(GTK_TEXT_VIEW(pdialog->message_area), mark);
503 }
504 gtk_text_buffer_delete_mark(buf, mark);
505}
height
struct canvas int int struct sprite int int int int height
Definition canvas_g.h:44
width
struct canvas int int struct sprite int int int width
Definition canvas_g.h:44
incite_cost
char * incite_cost
Definition comments.c:74
fcintl.h
_
#define _(String)
Definition fcintl.h:67
ftc_luaconsole_input
const struct ft_color ftc_luaconsole_input
Definition featured_text.c:99
featured_text.h
text_tag_list_iterate_end
#define text_tag_list_iterate_end
Definition featured_text.h:116
text_tag_list_iterate
#define text_tag_list_iterate(tags, ptag)
Definition featured_text.h:114
ft_offset_t
int ft_offset_t
Definition featured_text.h:102
game.h
genlist_remove
bool genlist_remove(struct genlist *pgenlist, const void *punlink)
Definition genlist.c:322
genlist_new
struct genlist * genlist_new(void)
Definition genlist.c:31
genlist_get
void * genlist_get(const struct genlist *pgenlist, int idx)
Definition genlist.c:221
genlist_prepend
void genlist_prepend(struct genlist *pgenlist, void *data)
Definition genlist.c:500
genlist_destroy
void genlist_destroy(struct genlist *pgenlist)
Definition genlist.c:57
genlist_size
int genlist_size(const struct genlist *pgenlist)
Definition genlist.c:192
set_message_buffer_view_link_handlers
void set_message_buffer_view_link_handlers(GtkWidget *view)
Definition chatline.c:745
scroll_if_necessary
void scroll_if_necessary(GtkTextView *textview, GtkTextMark *scroll_target)
Definition chatline.c:558
apply_text_tag
void apply_text_tag(const struct text_tag *ptag, GtkTextBuffer *buf, ft_offset_t text_start_offset, const char *text)
Definition chatline.c:756
bottom_notebook
GtkWidget * bottom_notebook
Definition gui_main.c:129
toplevel
GtkWidget * toplevel
Definition gui_main.c:125
right_notebook
GtkWidget * right_notebook
Definition gui_main.c:129
GUI_GTK_OPTION
#define GUI_GTK_OPTION(optname)
Definition gui_main.h:25
gui_dialog_destroy
void gui_dialog_destroy(struct gui_dialog *dlg)
Definition gui_stuff.c:954
gui_dialog_present
void gui_dialog_present(struct gui_dialog *dlg)
Definition gui_stuff.c:835
gui_dialog_raise
void gui_dialog_raise(struct gui_dialog *dlg)
Definition gui_stuff.c:865
gui_dialog_new
void gui_dialog_new(struct gui_dialog **pdlg, GtkNotebook *notebook, gpointer user_data, bool check_top)
Definition gui_stuff.c:517
gui_dialog_response_set_callback
void gui_dialog_response_set_callback(struct gui_dialog *dlg, GUI_DIALOG_RESPONSE_FUN fun)
Definition gui_stuff.c:988
gui_dialog_show_all
void gui_dialog_show_all(struct gui_dialog *dlg)
Definition gui_stuff.c:795
gui_dialog_set_title
void gui_dialog_set_title(struct gui_dialog *dlg, const char *title)
Definition gui_stuff.c:935
gui_dialog_add_button
GtkWidget * gui_dialog_add_button(struct gui_dialog *dlg, const char *icon_name, const char *text, int response)
Definition gui_stuff.c:706
setup_dialog
void setup_dialog(GtkWidget *shell, GtkWidget *parent)
Definition gui_stuff.c:287
MAX_LUACONSOLE_HISTORY
#define MAX_LUACONSOLE_HISTORY
Definition luaconsole.c:46
luaconsole_dialog_popdown
void luaconsole_dialog_popdown(void)
Definition luaconsole.c:144
luaconsole_dialog_get
static struct luaconsole_data * luaconsole_dialog_get(void)
Definition luaconsole.c:118
luaconsole_dialog_scroll_to_bottom
static void luaconsole_dialog_scroll_to_bottom(void)
Definition luaconsole.c:414
luaconsole_dialog_init
void luaconsole_dialog_init(void)
Definition luaconsole.c:83
luaconsole_dialog_is_open
bool luaconsole_dialog_is_open(void)
Definition luaconsole.c:157
luaconsole_load_file_callback
static void luaconsole_load_file_callback(GtkWidget *widget, gint response, gpointer data)
Definition luaconsole.c:333
luaconsole_dialog_create
static void luaconsole_dialog_create(struct luaconsole_data *pdialog)
Definition luaconsole.c:183
luaconsole_response_callback
static void luaconsole_response_callback(struct gui_dialog *pgui_dialog, int response, gpointer data)
Definition luaconsole.c:289
luaconsole
static struct luaconsole_data * luaconsole
Definition luaconsole.c:58
luaconsole_dialog_refresh
static void luaconsole_dialog_refresh(struct luaconsole_data *pdialog)
Definition luaconsole.c:435
luaconsole_res
luaconsole_res
Definition luaconsole.c:42
LUACONSOLE_RES_OPEN
@ LUACONSOLE_RES_OPEN
Definition luaconsole.c:43
luaconsole_dialog_destroy
static void luaconsole_dialog_destroy(struct luaconsole_data *pdialog)
Definition luaconsole.c:443
luaconsole_input_return
static void luaconsole_input_return(GtkEntry *w, gpointer data)
Definition luaconsole.c:257
real_luaconsole_append
void real_luaconsole_append(const char *astring, const struct text_tag_list *tags)
Definition luaconsole.c:459
luaconsole_load_file_popup
static void luaconsole_load_file_popup(void)
Definition luaconsole.c:310
real_luaconsole_dialog_update
void real_luaconsole_dialog_update(void)
Definition luaconsole.c:169
luaconsole_dialog_popup
void luaconsole_dialog_popup(bool raise)
Definition luaconsole.c:126
luaconsole_input_handler
static gboolean luaconsole_input_handler(GtkWidget *w, GdkEventKey *ev)
Definition luaconsole.c:353
luaconsole_dialog_done
void luaconsole_dialog_done(void)
Definition luaconsole.c:101
gui_dialog_add_content_widget
void gui_dialog_add_content_widget(struct gui_dialog *dlg, GtkWidget *wdg)
Definition gui_stuff.c:1105
widget_destroyed
void widget_destroyed(GtkWidget *wdg, void *data)
Definition gui_stuff.c:1155
luaconsole_dialog_area_resize
static void luaconsole_dialog_area_resize(GtkWidget *widget, int width, int height, gpointer data)
Definition luaconsole.c:404
gui_stuff.h
chatline.h
gui_main.h
luaconsole.h
log.h
fc_assert_ret
#define fc_assert_ret(condition)
Definition log.h:191
fc_assert
#define fc_assert(condition)
Definition log.h:176
fc_assert_ret_val
#define fc_assert_ret_val(condition, val)
Definition log.h:194
luaconsole_welcome_message
void luaconsole_welcome_message(void)
Definition luaconsole_common.c:109
luaconsole_printf
void luaconsole_printf(const struct ft_color color, const char *format,...)
Definition luaconsole_common.c:87
fc_calloc
#define fc_calloc(n, esz)
Definition mem.h:38
fc_strdup
#define fc_strdup(str)
Definition mem.h:43
options.h
GUI_GTK_MSGCHAT_SPLIT
@ GUI_GTK_MSGCHAT_SPLIT
Definition options.h:67
script_client_do_file
bool script_client_do_file(const char *filename)
Definition script_client.c:89
script_client_do_string
bool script_client_do_string(const char *str)
Definition script_client.c:79
script_client.h
shared.h
astring
Definition astring.h:36
entry
Definition registry_ini.c:193
genlist
Definition genlist.h:59
gui_dialog
Definition gui_stuff.h:70
luaconsole_data
Definition luaconsole.c:48
luaconsole_data::shell
struct gui_dialog * shell
Definition luaconsole.c:49
luaconsole_data::history_list
struct genlist * history_list
Definition luaconsole.c:54
luaconsole_data::entry
GtkWidget * entry
Definition luaconsole.c:52
luaconsole_data::message_area
GtkTextView * message_area
Definition luaconsole.c:51
luaconsole_data::history_pos
int history_pos
Definition luaconsole.c:55
luaconsole_data::message_buffer
GtkTextBuffer * message_buffer
Definition luaconsole.c:50
widget
Definition widget.h:112
fc_localtime
struct tm * fc_localtime(const time_t *timep, struct tm *result)
Definition support.c:1301
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47