Removed silencing of gtk warning logs from gtk3.22-client.
[freeciv.git] / utility / shared.h
blob9971aebef74fb2cd62d20a36ec6e2ab41f019667
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 ***********************************************************************/
13 #ifndef FC__SHARED_H
14 #define FC__SHARED_H
16 #ifdef __cplusplus
17 extern "C" {
18 #endif /* __cplusplus */
20 #include <freeciv_config.h>
22 #include <stdlib.h> /* size_t */
23 #include <string.h> /* memset */
24 #include <time.h> /* time_t */
26 /* utility */
27 #include "log.h"
28 #include "support.h" /* bool, fc__attribute */
30 /* Changing these will break network compatability! */
31 #define MAX_LEN_ADDR 256 /* see also MAXHOSTNAMELEN and RFC 1123 2.1 */
32 #define MAX_LEN_PATH 4095
34 /* Use FC_INFINITY to denote that a certain event will never occur or
35 another unreachable condition. */
36 #define FC_INFINITY (1000 * 1000 * 1000)
38 #ifndef FREECIV_TESTMATIC
39 /* Initialize something for the sole purpose of silencing false compiler warning
40 * about variable possibly used uninitialized. */
41 #define BAD_HEURISTIC_INIT(_ini_val_) = _ini_val_
42 #else /* FREECIV_TESTMATIC */
43 #define BAD_HEURISTIC_INIT(_ini_val_)
44 #endif /* FREECIV_TESTMATIC */
46 enum fc_tristate { TRI_NO, TRI_YES, TRI_MAYBE };
47 #define BOOL_TO_TRISTATE(tri) ((tri) ? TRI_YES : TRI_NO)
49 #ifndef MAX
50 #define MAX(x,y) (((x)>(y))?(x):(y))
51 #define MIN(x,y) (((x)<(y))?(x):(y))
52 #endif
53 #define CLIP(lower,current,upper) \
54 ((current)<(lower)?(lower):(current)>(upper)?(upper):(current))
56 #ifndef ABS
57 #define ABS(x) (((x) >= 0) ? (x) : -(x))
58 #endif
60 /* Note: Solaris already has a WRAP macro that is completely different. */
61 #define FC_WRAP(value, range) \
62 ((value) < 0 \
63 ? ((value) % (range) != 0 ? (value) % (range) + (range) : 0) \
64 : ((value) >= (range) ? (value) % (range) : (value)))
66 #define BOOL_VAL(x) ((x) != 0)
67 #define XOR(p, q) (BOOL_VAL(p) != BOOL_VAL(q))
68 #define EQ(p, q) (BOOL_VAL(p) == BOOL_VAL(q))
71 * DIVIDE() divides and rounds down, rather than just divides and
72 * rounds toward 0. It is assumed that the divisor is positive.
74 #define DIVIDE(n, d) \
75 ( (n) / (d) - (( (n) < 0 && (n) % (d) < 0 ) ? 1 : 0) )
77 /* This is duplicated in rand.h to avoid extra includes: */
78 #define MAX_UINT32 0xFFFFFFFF
79 #define MAX_UINT16 0xFFFF
80 #define MAX_UINT8 0xFF
82 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
83 #define ADD_TO_POINTER(p, n) ((void *)((char *)(p)+(n)))
85 #define FC_MEMBER(type, member) (((type *) NULL)->member)
86 #define FC_MEMBER_OFFSETOF(type, member) ((size_t) &FC_MEMBER(type, member))
87 #define FC_MEMBER_SIZEOF(type, member) sizeof(FC_MEMBER(type, member))
88 #define FC_MEMBER_ARRAY_SIZE(type, member) \
89 ARRAY_SIZE(FC_MEMBER(type, member))
91 #define FC_INT_TO_PTR(i) ((void *) (intptr_t) (i))
92 #define FC_PTR_TO_INT(p) ((int) (intptr_t) (p))
93 #define FC_UINT_TO_PTR(u) ((void *) (intptr_t) (u))
94 #define FC_PTR_TO_UINT(p) ((unsigned int) (intptr_t) (p))
95 #define FC_SIZE_TO_PTR(s) ((void *) (intptr_t) (s))
96 #define FC_PTR_TO_SIZE(p) ((size_t) (intptr_t) (p))
98 /****************************************************************************
99 Used to initialize an array 'a' of size 'size' with value 'val' in each
100 element. Note that the value is evaluated for each element.
101 ****************************************************************************/
102 #define INITIALIZE_ARRAY(array, size, value) \
104 int _ini_index; \
106 for (_ini_index = 0; _ini_index < (size); _ini_index++) { \
107 (array)[_ini_index] = (value); \
111 #ifndef PATH_SEPARATOR
112 #if defined(FREECIV_MSWINDOWS) || defined(_WIN32) || defined(__WIN32__) || defined(__EMX__) || defined(__DJGPP__)
113 /* Win32, OS/2, DOS */
114 # define PATH_SEPARATOR ";"
115 #else
116 /* Unix */
117 # define PATH_SEPARATOR ":"
118 #endif
119 #endif /* PATH_SEPARATOR */
121 #if defined(FREECIV_MSWINDOWS) || defined(_WIN32) || defined(__WIN32__) || defined(__EMX__) || defined(__DJGPP__)
122 /* Win32, OS/2, DOS */
123 # define DIR_SEPARATOR "\\"
124 # define DIR_SEPARATOR_CHAR '\\'
125 #else
126 /* Unix */
127 # define DIR_SEPARATOR_IS_DEFAULT
128 # define DIR_SEPARATOR "/"
129 # define DIR_SEPARATOR_CHAR '/'
130 #endif
132 #define PARENT_DIR_OPERATOR ".."
134 char *create_centered_string(const char *s);
136 const char *big_int_to_text(unsigned int mantissa, unsigned int exponent);
137 const char *int_to_text(unsigned int number);
139 bool is_ascii_name(const char *name);
140 bool is_base64url(const char *s);
141 bool is_safe_filename(const char *name);
142 void randomize_base64url_string(char *s, size_t n);
144 int compare_strings(const void *first, const void *second);
145 int compare_strings_ptrs(const void *first, const void *second);
146 int compare_strings_strvec(const char *const *first,
147 const char *const *second);
149 char *skip_leading_spaces(char *s);
150 void remove_leading_spaces(char *s);
151 void remove_trailing_spaces(char *s);
152 void remove_leading_trailing_spaces(char *s);
154 bool check_strlen(const char *str, size_t len, const char *errmsg);
155 size_t loud_strlcpy(char *buffer, const char *str, size_t len,
156 const char *errmsg);
157 /* Convenience macro. */
158 #define sz_loud_strlcpy(buffer, str, errmsg) \
159 loud_strlcpy(buffer, str, sizeof(buffer), errmsg)
161 char *end_of_strn(char *str, int *nleft);
163 bool str_to_int(const char *str, int *pint);
164 bool str_to_float(const char *str, float *pfloat);
166 /**************************************************************************
168 **************************************************************************/
169 struct fileinfo {
170 char *name; /* descriptive file name string */
171 char *fullname; /* full absolute filename */
172 time_t mtime; /* last modification time */
175 #define SPECLIST_TAG fileinfo
176 #define SPECLIST_TYPE struct fileinfo
177 #include "speclist.h"
178 #define fileinfo_list_iterate(list, pnode) \
179 TYPED_LIST_ITERATE(struct fileinfo, list, pnode)
180 #define fileinfo_list_iterate_end LIST_ITERATE_END
182 char *user_home_dir(void);
183 void free_user_home_dir(void);
184 char *user_username(char *buf, size_t bufsz);
186 const struct strvec *get_data_dirs(void);
187 const struct strvec *get_save_dirs(void);
188 const struct strvec *get_scenario_dirs(void);
190 void free_data_dir_names(void);
192 struct strvec *fileinfolist(const struct strvec *dirs, const char *suffix);
193 struct fileinfo_list *fileinfolist_infix(const struct strvec *dirs,
194 const char *infix, bool nodups);
195 const char *fileinfoname(const struct strvec *dirs, const char *filename);
196 void free_fileinfo_data(void);
198 void init_nls(void);
199 void free_nls(void);
200 char *setup_langname(void);
202 void dont_run_as_root(const char *argv0, const char *fallback);
204 /*** matching prefixes: ***/
206 enum m_pre_result {
207 M_PRE_EXACT, /* matches with exact length */
208 M_PRE_ONLY, /* only matching prefix */
209 M_PRE_AMBIGUOUS, /* first of multiple matching prefixes */
210 M_PRE_EMPTY, /* prefix is empty string (no match) */
211 M_PRE_LONG, /* prefix is too long (no match) */
212 M_PRE_FAIL, /* no match at all */
213 M_PRE_LAST /* flag value */
216 const char *m_pre_description(enum m_pre_result result);
218 /* function type to access a name from an index: */
219 typedef const char *(*m_pre_accessor_fn_t)(int);
221 /* function type to compare prefix: */
222 typedef int (*m_pre_strncmp_fn_t)(const char *, const char *, size_t n);
224 /* function type to calculate effective string length: */
225 typedef size_t (m_strlen_fn_t)(const char *str);
227 enum m_pre_result match_prefix(m_pre_accessor_fn_t accessor_fn,
228 size_t n_names,
229 size_t max_len_name,
230 m_pre_strncmp_fn_t cmp_fn,
231 m_strlen_fn_t len_fn,
232 const char *prefix,
233 int *ind_result);
234 enum m_pre_result match_prefix_full(m_pre_accessor_fn_t accessor_fn,
235 size_t n_names,
236 size_t max_len_name,
237 m_pre_strncmp_fn_t cmp_fn,
238 m_strlen_fn_t len_fn,
239 const char *prefix,
240 int *ind_result,
241 int *matches,
242 int max_matches,
243 int *pnum_matches);
245 char *get_multicast_group(bool ipv6_preferred);
246 void free_multicast_group(void);
247 void interpret_tilde(char* buf, size_t buf_size, const char* filename);
248 char *interpret_tilde_alloc(const char* filename);
249 char *skip_to_basename(char *filepath);
251 bool make_dir(const char *pathname);
252 bool path_is_absolute(const char *filename);
254 char scanin(const char **buf, char *delimiters, char *dest, int size);
256 void array_shuffle(int *array, int n);
258 void format_time_duration(time_t t, char *buf, int maxlen);
260 bool wildcard_fit_string(const char *pattern, const char *test);
262 /* Custom format strings. */
263 struct cf_sequence;
265 int fc_snprintcf(char *buf, size_t buf_len, const char *format, ...)
266 fc__attribute((nonnull (1, 3))); /* Not a printf format. */
267 int fc_vsnprintcf(char *buf, size_t buf_len, const char *format,
268 const struct cf_sequence *sequences, size_t sequences_num)
269 fc__attribute((nonnull (1, 3, 4)));
271 /* Tools for fc_snprintcf(). */
272 static inline struct cf_sequence cf_bool_seq(char letter, bool value);
273 static inline struct cf_sequence cf_trans_bool_seq(char letter, bool value);
274 static inline struct cf_sequence cf_char_seq(char letter, char value);
275 static inline void cf_int_seq(char letter, int value, struct cf_sequence *out);
276 static inline struct cf_sequence cf_hexa_seq(char letter, int value);
277 static inline struct cf_sequence cf_float_seq(char letter, float value);
278 static inline struct cf_sequence cf_ptr_seq(char letter, const void *value);
279 static inline struct cf_sequence cf_str_seq(char letter, const char *value);
280 static inline struct cf_sequence cf_end(void);
282 enum cf_type {
283 CF_BOOLEAN,
284 CF_TRANS_BOOLEAN,
285 CF_CHARACTER,
286 CF_INTEGER,
287 CF_HEXA,
288 CF_FLOAT,
289 CF_POINTER,
290 CF_STRING,
292 CF_LAST = -1
295 struct cf_sequence {
296 enum cf_type type;
297 char letter;
298 union {
299 bool bool_value;
300 char char_value;
301 int int_value;
302 float float_value;
303 const void *ptr_value;
304 const char *str_value;
308 /****************************************************************************
309 Build an argument for fc_snprintcf() of boolean type.
310 ****************************************************************************/
311 static inline struct cf_sequence cf_bool_seq(char letter, bool value)
313 struct cf_sequence sequence;
315 sequence.type = CF_BOOLEAN;
316 sequence.letter = letter;
317 sequence.bool_value = value;
319 return sequence;
322 /****************************************************************************
323 Build an argument for fc_snprintcf() of boolean type (result will be
324 translated).
325 ****************************************************************************/
326 static inline struct cf_sequence cf_trans_bool_seq(char letter, bool value)
328 struct cf_sequence sequence;
330 sequence.type = CF_TRANS_BOOLEAN;
331 sequence.letter = letter;
332 sequence.bool_value = value;
334 return sequence;
337 /****************************************************************************
338 Build an argument for fc_snprintcf() of character type (%c).
339 ****************************************************************************/
340 static inline struct cf_sequence cf_char_seq(char letter, char value)
342 struct cf_sequence sequence;
344 sequence.type = CF_CHARACTER;
345 sequence.letter = letter;
346 sequence.char_value = value;
348 return sequence;
351 /****************************************************************************
352 Build an argument for fc_snprintcf() of integer type (%d).
353 ****************************************************************************/
354 static inline void cf_int_seq(char letter, int value, struct cf_sequence *out)
356 out->type = CF_INTEGER;
357 out->letter = letter;
358 out->int_value = value;
361 /****************************************************************************
362 Build an argument for fc_snprintcf() of hexadecimal type (%x).
363 ****************************************************************************/
364 static inline struct cf_sequence cf_hexa_seq(char letter, int value)
366 struct cf_sequence sequence;
368 sequence.type = CF_HEXA;
369 sequence.letter = letter;
370 sequence.int_value = value;
372 return sequence;
375 /****************************************************************************
376 Build an argument for fc_snprintcf() of float type (%f).
377 ****************************************************************************/
378 static inline struct cf_sequence cf_float_seq(char letter, float value)
380 struct cf_sequence sequence;
382 sequence.type = CF_FLOAT;
383 sequence.letter = letter;
384 sequence.float_value = value;
386 return sequence;
389 /****************************************************************************
390 Build an argument for fc_snprintcf() of pointer type (%p).
391 ****************************************************************************/
392 static inline struct cf_sequence cf_ptr_seq(char letter, const void *value)
394 struct cf_sequence sequence;
396 sequence.type = CF_POINTER;
397 sequence.letter = letter;
398 sequence.ptr_value = value;
400 return sequence;
403 /****************************************************************************
404 Build an argument for fc_snprintcf() of string type (%s).
405 ****************************************************************************/
406 static inline struct cf_sequence cf_str_seq(char letter, const char *value)
408 struct cf_sequence sequence;
410 sequence.type = CF_STRING;
411 sequence.letter = letter;
412 sequence.str_value = value;
414 return sequence;
417 /****************************************************************************
418 Must finish the list of the arguments of fc_snprintcf().
419 ****************************************************************************/
420 static inline struct cf_sequence cf_end(void)
422 struct cf_sequence sequence;
424 sequence.type = CF_LAST;
426 return sequence;
429 bool formats_match(const char *format1, const char *format2);
431 #ifdef __cplusplus
433 #endif /* __cplusplus */
435 #endif /* FC__SHARED_H */