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 ***********************************************************************/
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 */
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)
50 #define MAX(x,y) (((x)>(y))?(x):(y))
51 #define MIN(x,y) (((x)<(y))?(x):(y))
53 #define CLIP(lower,current,upper) \
54 ((current)<(lower)?(lower):(current)>(upper)?(upper):(current))
57 #define ABS(x) (((x) >= 0) ? (x) : -(x))
60 /* Note: Solaris already has a WRAP macro that is completely different. */
61 #define FC_WRAP(value, range) \
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) \
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 ";"
117 # define PATH_SEPARATOR ":"
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 '\\'
127 # define DIR_SEPARATOR_IS_DEFAULT
128 # define DIR_SEPARATOR "/"
129 # define DIR_SEPARATOR_CHAR '/'
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
,
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 **************************************************************************/
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);
200 char *setup_langname(void);
202 void dont_run_as_root(const char *argv0
, const char *fallback
);
204 /*** matching prefixes: ***/
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
,
230 m_pre_strncmp_fn_t cmp_fn
,
231 m_strlen_fn_t len_fn
,
234 enum m_pre_result
match_prefix_full(m_pre_accessor_fn_t accessor_fn
,
237 m_pre_strncmp_fn_t cmp_fn
,
238 m_strlen_fn_t len_fn
,
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. */
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);
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
;
322 /****************************************************************************
323 Build an argument for fc_snprintcf() of boolean type (result will be
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
;
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
;
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
;
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
;
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
;
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
;
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
;
429 bool formats_match(const char *format1
, const char *format2
);
433 #endif /* __cplusplus */
435 #endif /* FC__SHARED_H */