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)
49 enum fc_tristate
fc_tristate_and(enum fc_tristate one
,
50 enum fc_tristate two
);
53 #define MAX(x,y) (((x)>(y))?(x):(y))
54 #define MIN(x,y) (((x)<(y))?(x):(y))
56 #define CLIP(lower,current,upper) \
57 ((current)<(lower)?(lower):(current)>(upper)?(upper):(current))
60 #define ABS(x) (((x) >= 0) ? (x) : -(x))
63 /* Note: Solaris already has a WRAP macro that is completely different. */
64 #define FC_WRAP(value, range) \
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) \
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 ";"
119 # define PATH_SEPARATOR ":"
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 '\\'
129 # define DIR_SEPARATOR_IS_DEFAULT
130 # define DIR_SEPARATOR "/"
131 # define DIR_SEPARATOR_CHAR '/'
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
,
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
);
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);
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: ***/
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
,
233 m_pre_strncmp_fn_t cmp_fn
,
234 m_strlen_fn_t len_fn
,
237 enum m_pre_result
match_prefix_full(m_pre_accessor_fn_t accessor_fn
,
240 m_pre_strncmp_fn_t cmp_fn
,
241 m_strlen_fn_t len_fn
,
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. */
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);
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
;
325 /****************************************************************************
326 Build an argument for fc_snprintcf() of boolean type (result will be
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
;
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
;
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
;
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
;
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
;
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
;
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
;
432 bool formats_match(const char *format1
, const char *format2
);
436 #endif /* __cplusplus */
438 #endif /* FC__SHARED_H */