webperimental: killstack decides stack protects.
[freeciv.git] / utility / shared.h
blobf2ffa110111f3f547fe0fc895a912a0ea49a9faa
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 enum fc_tristate fc_tristate_and(enum fc_tristate one,
50 enum fc_tristate two);
52 #ifndef MAX
53 #define MAX(x,y) (((x)>(y))?(x):(y))
54 #define MIN(x,y) (((x)<(y))?(x):(y))
55 #endif
56 #define CLIP(lower,current,upper) \
57 ((current)<(lower)?(lower):(current)>(upper)?(upper):(current))
59 #ifndef ABS
60 #define ABS(x) (((x) >= 0) ? (x) : -(x))
61 #endif
63 /* Note: Solaris already has a WRAP macro that is completely different. */
64 #define FC_WRAP(value, range) \
65 ((value) < 0 \
66 ? ((value) % (range) != 0 ? (value) % (range) + (range) : 0) \
67 : ((value) >= (range) ? (value) % (range) : (value)))
69 #define BOOL_VAL(x) ((x) != 0)
70 #define XOR(p, q) (BOOL_VAL(p) != BOOL_VAL(q))
71 #define EQ(p, q) (BOOL_VAL(p) == BOOL_VAL(q))
74 * DIVIDE() divides and rounds down, rather than just divides and
75 * rounds toward 0. It is assumed that the divisor is positive.
77 #define DIVIDE(n, d) \
78 ( (n) / (d) - (( (n) < 0 && (n) % (d) < 0 ) ? 1 : 0) )
80 #define MAX_UINT32 0xFFFFFFFF
81 #define MAX_UINT16 0xFFFF
82 #define MAX_UINT8 0xFF
84 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
85 #define ADD_TO_POINTER(p, n) ((void *)((char *)(p)+(n)))
87 #define FC_MEMBER(type, member) (((type *) NULL)->member)
88 #define FC_MEMBER_OFFSETOF(type, member) ((size_t) &FC_MEMBER(type, member))
89 #define FC_MEMBER_SIZEOF(type, member) sizeof(FC_MEMBER(type, member))
90 #define FC_MEMBER_ARRAY_SIZE(type, member) \
91 ARRAY_SIZE(FC_MEMBER(type, member))
93 #define FC_INT_TO_PTR(i) ((void *) (intptr_t) (i))
94 #define FC_PTR_TO_INT(p) ((int) (intptr_t) (p))
95 #define FC_UINT_TO_PTR(u) ((void *) (intptr_t) (u))
96 #define FC_PTR_TO_UINT(p) ((unsigned int) (intptr_t) (p))
97 #define FC_SIZE_TO_PTR(s) ((void *) (intptr_t) (s))
98 #define FC_PTR_TO_SIZE(p) ((size_t) (intptr_t) (p))
100 /****************************************************************************
101 Used to initialize an array 'a' of size 'size' with value 'val' in each
102 element. Note that the value is evaluated for each element.
103 ****************************************************************************/
104 #define INITIALIZE_ARRAY(array, size, value) \
106 int _ini_index; \
108 for (_ini_index = 0; _ini_index < (size); _ini_index++) { \
109 (array)[_ini_index] = (value); \
113 #ifndef PATH_SEPARATOR
114 #if defined(FREECIV_MSWINDOWS) || defined(_WIN32) || defined(__WIN32__) || defined(__EMX__) || defined(__DJGPP__)
115 /* Win32, OS/2, DOS */
116 # define PATH_SEPARATOR ";"
117 #else
118 /* Unix */
119 # define PATH_SEPARATOR ":"
120 #endif
121 #endif /* PATH_SEPARATOR */
123 #if defined(FREECIV_MSWINDOWS) || defined(_WIN32) || defined(__WIN32__) || defined(__EMX__) || defined(__DJGPP__)
124 /* Win32, OS/2, DOS */
125 # define DIR_SEPARATOR "\\"
126 # define DIR_SEPARATOR_CHAR '\\'
127 #else
128 /* Unix */
129 # define DIR_SEPARATOR_IS_DEFAULT
130 # define DIR_SEPARATOR "/"
131 # define DIR_SEPARATOR_CHAR '/'
132 #endif
134 #define PARENT_DIR_OPERATOR ".."
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);
185 char *freeciv_storage_dir(void);
186 void free_freeciv_storage_dir(void);
188 const struct strvec *get_data_dirs(void);
189 const struct strvec *get_save_dirs(void);
190 const struct strvec *get_scenario_dirs(void);
192 void free_data_dir_names(void);
194 struct strvec *fileinfolist(const struct strvec *dirs, const char *suffix);
195 struct fileinfo_list *fileinfolist_infix(const struct strvec *dirs,
196 const char *infix, bool nodups);
197 const char *fileinfoname(const struct strvec *dirs, const char *filename);
198 void free_fileinfo_data(void);
200 void init_nls(void);
201 void free_nls(void);
202 char *setup_langname(void);
203 void switch_lang(const char *lang);
205 void dont_run_as_root(const char *argv0, const char *fallback);
207 /*** matching prefixes: ***/
209 enum m_pre_result {
210 M_PRE_EXACT, /* matches with exact length */
211 M_PRE_ONLY, /* only matching prefix */
212 M_PRE_AMBIGUOUS, /* first of multiple matching prefixes */
213 M_PRE_EMPTY, /* prefix is empty string (no match) */
214 M_PRE_LONG, /* prefix is too long (no match) */
215 M_PRE_FAIL, /* no match at all */
216 M_PRE_LAST /* flag value */
219 const char *m_pre_description(enum m_pre_result result);
221 /* function type to access a name from an index: */
222 typedef const char *(*m_pre_accessor_fn_t)(int);
224 /* function type to compare prefix: */
225 typedef int (*m_pre_strncmp_fn_t)(const char *, const char *, size_t n);
227 /* function type to calculate effective string length: */
228 typedef size_t (m_strlen_fn_t)(const char *str);
230 enum m_pre_result match_prefix(m_pre_accessor_fn_t accessor_fn,
231 size_t n_names,
232 size_t max_len_name,
233 m_pre_strncmp_fn_t cmp_fn,
234 m_strlen_fn_t len_fn,
235 const char *prefix,
236 int *ind_result);
237 enum m_pre_result match_prefix_full(m_pre_accessor_fn_t accessor_fn,
238 size_t n_names,
239 size_t max_len_name,
240 m_pre_strncmp_fn_t cmp_fn,
241 m_strlen_fn_t len_fn,
242 const char *prefix,
243 int *ind_result,
244 int *matches,
245 int max_matches,
246 int *pnum_matches);
248 char *get_multicast_group(bool ipv6_preferred);
249 void free_multicast_group(void);
250 void interpret_tilde(char* buf, size_t buf_size, const char* filename);
251 char *interpret_tilde_alloc(const char* filename);
252 char *skip_to_basename(char *filepath);
254 bool make_dir(const char *pathname);
255 bool path_is_absolute(const char *filename);
257 char scanin(const char **buf, char *delimiters, char *dest, int size);
259 void array_shuffle(int *array, int n);
261 void format_time_duration(time_t t, char *buf, int maxlen);
263 bool wildcard_fit_string(const char *pattern, const char *test);
265 /* Custom format strings. */
266 struct cf_sequence;
268 int fc_snprintcf(char *buf, size_t buf_len, const char *format, ...)
269 fc__attribute((nonnull (1, 3))); /* Not a printf format. */
270 int fc_vsnprintcf(char *buf, size_t buf_len, const char *format,
271 const struct cf_sequence *sequences, size_t sequences_num)
272 fc__attribute((nonnull (1, 3, 4)));
274 /* Tools for fc_snprintcf(). */
275 static inline struct cf_sequence cf_bool_seq(char letter, bool value);
276 static inline struct cf_sequence cf_trans_bool_seq(char letter, bool value);
277 static inline struct cf_sequence cf_char_seq(char letter, char value);
278 static inline void cf_int_seq(char letter, int value, struct cf_sequence *out);
279 static inline struct cf_sequence cf_hexa_seq(char letter, int value);
280 static inline struct cf_sequence cf_float_seq(char letter, float value);
281 static inline struct cf_sequence cf_ptr_seq(char letter, const void *value);
282 static inline struct cf_sequence cf_str_seq(char letter, const char *value);
283 static inline struct cf_sequence cf_end(void);
285 enum cf_type {
286 CF_BOOLEAN,
287 CF_TRANS_BOOLEAN,
288 CF_CHARACTER,
289 CF_INTEGER,
290 CF_HEXA,
291 CF_FLOAT,
292 CF_POINTER,
293 CF_STRING,
295 CF_LAST = -1
298 struct cf_sequence {
299 enum cf_type type;
300 char letter;
301 union {
302 bool bool_value;
303 char char_value;
304 int int_value;
305 float float_value;
306 const void *ptr_value;
307 const char *str_value;
311 /****************************************************************************
312 Build an argument for fc_snprintcf() of boolean type.
313 ****************************************************************************/
314 static inline struct cf_sequence cf_bool_seq(char letter, bool value)
316 struct cf_sequence sequence;
318 sequence.type = CF_BOOLEAN;
319 sequence.letter = letter;
320 sequence.bool_value = value;
322 return sequence;
325 /****************************************************************************
326 Build an argument for fc_snprintcf() of boolean type (result will be
327 translated).
328 ****************************************************************************/
329 static inline struct cf_sequence cf_trans_bool_seq(char letter, bool value)
331 struct cf_sequence sequence;
333 sequence.type = CF_TRANS_BOOLEAN;
334 sequence.letter = letter;
335 sequence.bool_value = value;
337 return sequence;
340 /****************************************************************************
341 Build an argument for fc_snprintcf() of character type (%c).
342 ****************************************************************************/
343 static inline struct cf_sequence cf_char_seq(char letter, char value)
345 struct cf_sequence sequence;
347 sequence.type = CF_CHARACTER;
348 sequence.letter = letter;
349 sequence.char_value = value;
351 return sequence;
354 /****************************************************************************
355 Build an argument for fc_snprintcf() of integer type (%d).
356 ****************************************************************************/
357 static inline void cf_int_seq(char letter, int value, struct cf_sequence *out)
359 out->type = CF_INTEGER;
360 out->letter = letter;
361 out->int_value = value;
364 /****************************************************************************
365 Build an argument for fc_snprintcf() of hexadecimal type (%x).
366 ****************************************************************************/
367 static inline struct cf_sequence cf_hexa_seq(char letter, int value)
369 struct cf_sequence sequence;
371 sequence.type = CF_HEXA;
372 sequence.letter = letter;
373 sequence.int_value = value;
375 return sequence;
378 /****************************************************************************
379 Build an argument for fc_snprintcf() of float type (%f).
380 ****************************************************************************/
381 static inline struct cf_sequence cf_float_seq(char letter, float value)
383 struct cf_sequence sequence;
385 sequence.type = CF_FLOAT;
386 sequence.letter = letter;
387 sequence.float_value = value;
389 return sequence;
392 /****************************************************************************
393 Build an argument for fc_snprintcf() of pointer type (%p).
394 ****************************************************************************/
395 static inline struct cf_sequence cf_ptr_seq(char letter, const void *value)
397 struct cf_sequence sequence;
399 sequence.type = CF_POINTER;
400 sequence.letter = letter;
401 sequence.ptr_value = value;
403 return sequence;
406 /****************************************************************************
407 Build an argument for fc_snprintcf() of string type (%s).
408 ****************************************************************************/
409 static inline struct cf_sequence cf_str_seq(char letter, const char *value)
411 struct cf_sequence sequence;
413 sequence.type = CF_STRING;
414 sequence.letter = letter;
415 sequence.str_value = value;
417 return sequence;
420 /****************************************************************************
421 Must finish the list of the arguments of fc_snprintcf().
422 ****************************************************************************/
423 static inline struct cf_sequence cf_end(void)
425 struct cf_sequence sequence;
427 sequence.type = CF_LAST;
429 return sequence;
432 bool formats_match(const char *format1, const char *format2);
434 #ifdef __cplusplus
436 #endif /* __cplusplus */
438 #endif /* FC__SHARED_H */