Freeciv21
Develop your civilization from humble roots to a global empire
shared.h
Go to the documentation of this file.
1 /*__ ___ ***************************************
2 / \ / \ Copyright (c) 1996-2020 Freeciv21 and Freeciv
3 \_ \ / __/ contributors. This file is part of Freeciv21.
4  _\ \ / /__ Freeciv21 is free software: you can redistribute it
5  \___ \____/ __/ and/or modify it under the terms of the GNU General
6  \_ _/ Public License as published by the Free Software
7  | @ @ \_ Foundation, either version 3 of the License,
8  | or (at your option) any later version.
9  _/ /\ You should have received a copy of the GNU
10  /o) (o/\ \_ General Public License along with Freeciv21.
11  \_____/ / If not, see https://www.gnu.org/licenses/.
12  \____/ ********************************************************/
13 #pragma once
14 
15 // utility
16 #include "support.h" // bool, fc__attribute
17 
18 #include <QFileInfoList>
19 #include <QString>
20 #include <QStringList>
21 
22 #include <time.h>
23 
24 template <typename T> class QVector;
25 
26 // Changing these will break network compatability!
27 #define MAX_LEN_ADDR 256 // see also MAXHOSTNAMELEN and RFC 1123 2.1
28 #define MAX_LEN_PATH 4095
29 
30 /* Use FC_INFINITY to denote that a certain event will never occur or
31  another unreachable condition. */
32 #define FC_INFINITY (1000 * 1000 * 1000)
33 
34 #ifndef FREECIV_TESTMATIC
35 /* Initialize something for the sole purpose of silencing false compiler
36  * warning about variable possibly used uninitialized. */
37 #define BAD_HEURISTIC_INIT(_ini_val_) = _ini_val_
38 #else // FREECIV_TESTMATIC
39 #define BAD_HEURISTIC_INIT(_ini_val_)
40 #endif // FREECIV_TESTMATIC
41 
43 #define BOOL_TO_TRISTATE(tri) ((tri) ? TRI_YES : TRI_NO)
44 
45 enum fc_tristate fc_tristate_and(enum fc_tristate one, enum fc_tristate two);
46 
47 #ifndef MAX
48 #define MAX(x, y) (((x) > (y)) ? (x) : (y))
49 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
50 #endif
51 #define CLIP(lower, current, upper) \
52  ((current) < (lower) ? (lower) : (current) > (upper) ? (upper) : (current))
53 
54 #ifndef ABS
55 #define ABS(x) (((x) >= 0) ? (x) : -(x))
56 #endif
57 
58 // Note: Solaris already has a WRAP macro that is completely different.
59 #define FC_WRAP(value, range) \
60  ((value) < 0 ? ((value) % (range) != 0 ? (value) % (range) + (range) : 0) \
61  : ((value) >= (range) ? (value) % (range) : (value)))
62 
63 #define BOOL_VAL(x) ((x) != 0)
64 #define XOR(p, q) (BOOL_VAL(p) != BOOL_VAL(q))
65 #define EQ(p, q) (BOOL_VAL(p) == BOOL_VAL(q))
66 
67 /*
68  * DIVIDE() divides and rounds down, rather than just divides and
69  * rounds toward 0. It is assumed that the divisor is positive.
70  */
71 #define DIVIDE(n, d) ((n) / (d) - (((n) < 0 && (n) % (d) < 0) ? 1 : 0))
72 
73 #define MAX_UINT32 0xFFFFFFFF
74 #define MAX_UINT16 0xFFFF
75 #define MAX_UINT8 0xFF
76 
77 // Can't use sizeof() because of the lambda in assert(), see
78 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60855
79 #define ARRAY_SIZE(x) (*(&(x) + 1) - (x))
80 #define ADD_TO_POINTER(p, n) ((void *) ((char *) (p) + (n)))
81 
82 #define FC_MEMBER(type, member) (((type *) nullptr)->member)
83 #define FC_MEMBER_OFFSETOF(type, member) ((size_t) &FC_MEMBER(type, member))
84 #define FC_MEMBER_SIZEOF(type, member) sizeof(FC_MEMBER(type, member))
85 #define FC_MEMBER_ARRAY_SIZE(type, member) \
86  ARRAY_SIZE(FC_MEMBER(type, member))
87 
88 #define FC_INT_TO_PTR(i) ((void *) (intptr_t)(i))
89 #define FC_PTR_TO_INT(p) ((int) (intptr_t)(p))
90 #define FC_UINT_TO_PTR(u) ((void *) (intptr_t)(u))
91 #define FC_PTR_TO_UINT(p) ((unsigned int) (intptr_t)(p))
92 #define FC_SIZE_TO_PTR(s) ((void *) (intptr_t)(s))
93 #define FC_PTR_TO_SIZE(p) ((size_t)(intptr_t)(p))
94 
95 /****************************************************************************
96  Used to initialize an array 'a' of size 'size' with value 'val' in each
97  element. Note that the value is evaluated for each element.
98 ****************************************************************************/
99 #define INITIALIZE_ARRAY(array, size, value) \
100  { \
101  int _ini_index; \
102  \
103  for (_ini_index = 0; _ini_index < (size); _ini_index++) { \
104  (array)[_ini_index] = (value); \
105  } \
106  }
107 
108 #define PARENT_DIR_OPERATOR ".."
109 
110 const char *big_int_to_text(unsigned int mantissa, unsigned int exponent);
111 const char *int_to_text(unsigned int number);
112 
113 bool is_ascii_name(const char *name);
114 bool is_base64url(const char *s);
115 bool is_safe_filename(const QString &name);
116 void randomize_base64url_string(char *s, size_t n);
117 
118 char *skip_leading_spaces(char *s);
119 void remove_leading_spaces(char *s);
120 void remove_trailing_spaces(char *s);
121 void remove_leading_trailing_spaces(char *s);
122 
123 bool check_strlen(const char *str, size_t len, const char *errmsg);
124 size_t loud_strlcpy(char *buffer, const char *str, size_t len,
125  const char *errmsg);
126 // Convenience macro.
127 #define sz_loud_strlcpy(buffer, str, errmsg) \
128  loud_strlcpy(buffer, str, sizeof(buffer), errmsg)
129 
130 bool str_to_int(const char *str, int *pint);
131 
132 char *user_username(char *buf, size_t bufsz);
133 QString freeciv_storage_dir();
134 
135 const QStringList &get_data_dirs();
136 const QStringList &get_save_dirs();
137 const QStringList &get_scenario_dirs();
138 
139 QVector<QString> *fileinfolist(const QStringList &dirs, const char *suffix);
140 QFileInfoList find_files_in_path(const QStringList &path,
141  const QString &pattern, bool nodups);
142 QString fileinfoname(const QStringList &dirs, const QString &filename);
143 
144 void init_nls();
145 void free_nls();
146 char *setup_langname();
147 
148 void dont_run_as_root(const char *argv0, const char *fallback);
149 
150 /*** matching prefixes: ***/
151 
153  M_PRE_EXACT, // matches with exact length
154  M_PRE_ONLY, // only matching prefix
155  M_PRE_AMBIGUOUS, // first of multiple matching prefixes
156  M_PRE_EMPTY, // prefix is empty string (no match)
157  M_PRE_LONG, // prefix is too long (no match)
158  M_PRE_FAIL, // no match at all
159  M_PRE_LAST // flag value
160 };
161 
162 const char *m_pre_description(enum m_pre_result result);
163 
164 // function type to access a name from an index:
165 typedef const char *(*m_pre_accessor_fn_t)(int);
166 
167 // function type to compare prefix:
168 typedef int (*m_pre_strncmp_fn_t)(const char *, const char *, size_t n);
169 
170 // function type to calculate effective string length:
171 typedef size_t(m_strlen_fn_t)(const char *str);
172 
174  size_t n_names, size_t max_len_name,
175  m_pre_strncmp_fn_t cmp_fn,
176  m_strlen_fn_t len_fn, const char *prefix,
177  int *ind_result);
179  size_t n_names, size_t max_len_name,
180  m_pre_strncmp_fn_t cmp_fn,
181  m_strlen_fn_t len_fn, const char *prefix,
182  int *ind_result, int *matches,
183  int max_matches, int *pnum_matches);
184 
185 char *get_multicast_group(bool ipv6_preferred);
186 void free_multicast_group();
187 
188 QString interpret_tilde(const QString &filename);
189 
190 bool make_dir(const QString &pathname);
191 
192 char scanin(char **buf, char *delimiters, char *dest, int size);
193 
194 void array_shuffle(int *array, int n);
195 
196 void format_time_duration(time_t t, char *buf, int maxlen);
197 
198 bool wildcard_fit_string(const char *pattern, const char *test);
199 
200 // Custom format strings.
201 struct cf_sequence;
202 
203 int fc_vsnprintcf(char *buf, size_t buf_len, const char *format,
204  const struct cf_sequence *sequences, size_t sequences_num)
205  fc__attribute((nonnull(1, 3, 4)));
206 
207 static inline void cf_int_seq(char letter, int value,
208  struct cf_sequence *out);
209 static inline struct cf_sequence cf_str_seq(char letter, const char *value);
210 static inline struct cf_sequence cf_end();
211 
212 enum cf_type {
221 
222  CF_LAST = -1
223 };
224 
225 struct cf_sequence {
226  enum cf_type type;
227  char letter;
228  union {
232  float float_value;
233  const void *ptr_value;
234  const char *str_value;
235  };
236 };
237 
238 /****************************************************************************
239  Build an argument for fc_snprintcf() of integer type (%d).
240 ****************************************************************************/
241 static inline void cf_int_seq(char letter, int value,
242  struct cf_sequence *out)
243 {
244  out->type = CF_INTEGER;
245  out->letter = letter;
246  out->int_value = value;
247 }
248 
249 /****************************************************************************
250  Build an argument for fc_snprintcf() of string type (%s).
251 ****************************************************************************/
252 static inline struct cf_sequence cf_str_seq(char letter, const char *value)
253 {
254  struct cf_sequence sequence;
255 
256  sequence.type = CF_STRING;
257  sequence.letter = letter;
258  sequence.str_value = value;
259 
260  return sequence;
261 }
262 
263 /****************************************************************************
264  Must finish the list of the arguments of fc_snprintcf().
265 ****************************************************************************/
266 static inline struct cf_sequence cf_end()
267 {
268  struct cf_sequence sequence;
269 
270  sequence.type = CF_LAST;
271  sequence.letter = '\0';
272  sequence.bool_value = false;
273 
274  return sequence;
275 }
276 
277 bool formats_match(const char *format1, const char *format2);
Definition: shared.h:24
const char * name
Definition: inputfile.cpp:118
int len
Definition: packhand.cpp:127
fc_tristate
Definition: shared.h:42
@ TRI_YES
Definition: shared.h:42
@ TRI_NO
Definition: shared.h:42
@ TRI_MAYBE
Definition: shared.h:42
void format_time_duration(time_t t, char *buf, int maxlen)
Convenience function to nicely format a time_t seconds value in to a string with hours,...
Definition: shared.cpp:1187
int(* m_pre_strncmp_fn_t)(const char *, const char *, size_t n)
Definition: shared.h:168
char * skip_leading_spaces(char *s)
Returns 's' incremented to first non-space character.
Definition: shared.cpp:297
enum fc_tristate fc_tristate_and(enum fc_tristate one, enum fc_tristate two)
An AND function for fc_tristate.
Definition: shared.cpp:98
size_t() m_strlen_fn_t(const char *str)
Definition: shared.h:171
void dont_run_as_root(const char *argv0, const char *fallback)
If we have root privileges, die with an error.
Definition: shared.cpp:948
bool wildcard_fit_string(const char *pattern, const char *test)
Returns TRUE if test fit the pattern.
Definition: shared.cpp:1372
bool is_safe_filename(const QString &name)
Check if the name is safe security-wise.
Definition: shared.cpp:210
const QStringList & get_data_dirs()
Returns a list of data directory paths, in the order in which they should be searched.
Definition: shared.cpp:533
bool check_strlen(const char *str, size_t len, const char *errmsg)
Check the length of the given string.
Definition: shared.cpp:364
const char * m_pre_description(enum m_pre_result result)
Return a description string of the result.
Definition: shared.cpp:973
char * setup_langname()
Language environmental variable (with emulation).
Definition: shared.cpp:717
void remove_trailing_spaces(char *s)
Terminates string pointed to by 's' to remove traling spaces; Note 's' must point to writeable memory...
Definition: shared.cpp:330
const char * int_to_text(unsigned int number)
Return a prettily formatted string containing the given number.
Definition: shared.cpp:191
bool str_to_int(const char *str, int *pint)
Convert 'str' to it's int reprentation if possible.
Definition: shared.cpp:384
int static void cf_int_seq(char letter, int value, struct cf_sequence *out)
Definition: shared.h:241
static struct cf_sequence cf_str_seq(char letter, const char *value)
Definition: shared.h:252
const QStringList & get_save_dirs()
Returns a list of save directory paths, in the order in which they should be searched.
Definition: shared.cpp:563
const char * big_int_to_text(unsigned int mantissa, unsigned int exponent)
Returns a statically allocated string containing a nicely-formatted version of the given number accor...
Definition: shared.cpp:117
QString interpret_tilde(const QString &filename)
Interpret ~ in filename as home dir.
Definition: shared.cpp:1100
void free_nls()
Free memory allocated by Native Language Support.
Definition: shared.cpp:931
char scanin(char **buf, char *delimiters, char *dest, int size)
Scan in a word or set of words from start to but not including any of the given delimiters.
Definition: shared.cpp:1142
enum m_pre_result match_prefix_full(m_pre_accessor_fn_t accessor_fn, size_t n_names, size_t max_len_name, m_pre_strncmp_fn_t cmp_fn, m_strlen_fn_t len_fn, const char *prefix, int *ind_result, int *matches, int max_matches, int *pnum_matches)
Given n names, with maximum length max_len_name, accessed by accessor_fn(0) to accessor_fn(n-1),...
Definition: shared.cpp:1008
void init_nls()
Setup for Native Language Support, if configured to use it.
Definition: shared.cpp:871
cf_type
Definition: shared.h:212
@ CF_POINTER
Definition: shared.h:219
@ CF_HEXA
Definition: shared.h:217
@ CF_CHARACTER
Definition: shared.h:215
@ CF_INTEGER
Definition: shared.h:216
@ CF_TRANS_BOOLEAN
Definition: shared.h:214
@ CF_LAST
Definition: shared.h:222
@ CF_BOOLEAN
Definition: shared.h:213
@ CF_STRING
Definition: shared.h:220
@ CF_FLOAT
Definition: shared.h:218
size_t loud_strlcpy(char *buffer, const char *str, size_t len, const char *errmsg)
Call check_strlen() on str and then strlcpy() it into buffer.
Definition: shared.cpp:373
const char *(* m_pre_accessor_fn_t)(int)
Definition: shared.h:165
char * get_multicast_group(bool ipv6_preferred)
Returns string which gives the multicast group IP address for finding servers on the LAN,...
Definition: shared.cpp:1065
bool is_base64url(const char *s)
Check for valid base64url.
Definition: shared.cpp:258
void free_multicast_group()
Free multicast group resources.
Definition: shared.cpp:1091
QString fileinfoname(const QStringList &dirs, const QString &filename)
Returns a filename to access the specified file from a directory by searching all specified directori...
Definition: shared.cpp:661
static struct cf_sequence cf_end()
Definition: shared.h:266
bool formats_match(const char *format1, const char *format2)
Returns TRUE iff both formats are compatible (if 'format1' can be used instead 'format2' and reciproc...
Definition: shared.cpp:1621
QVector< QString > * fileinfolist(const QStringList &dirs, const char *suffix)
Returns a string vector storing the filenames in the data directories matching the given suffix.
Definition: shared.cpp:623
void remove_leading_spaces(char *s)
Removes leading spaces in string pointed to by 's'.
Definition: shared.cpp:312
char * user_username(char *buf, size_t bufsz)
Returns string which gives user's username, as specified by $USER or as given in password file for th...
Definition: shared.cpp:443
void array_shuffle(int *array, int n)
Randomize the elements of an array using the Fisher-Yates shuffle.
Definition: shared.cpp:1228
m_pre_result
Definition: shared.h:152
@ M_PRE_EXACT
Definition: shared.h:153
@ M_PRE_ONLY
Definition: shared.h:154
@ M_PRE_LAST
Definition: shared.h:159
@ M_PRE_LONG
Definition: shared.h:157
@ M_PRE_AMBIGUOUS
Definition: shared.h:155
@ M_PRE_EMPTY
Definition: shared.h:156
@ M_PRE_FAIL
Definition: shared.h:158
enum m_pre_result match_prefix(m_pre_accessor_fn_t accessor_fn, size_t n_names, size_t max_len_name, m_pre_strncmp_fn_t cmp_fn, m_strlen_fn_t len_fn, const char *prefix, int *ind_result)
See match_prefix_full().
Definition: shared.cpp:986
bool is_ascii_name(const char *name)
This is used in sundry places to make sure that names of cities, players etc.
Definition: shared.cpp:223
bool make_dir(const QString &pathname)
If the directory "pathname" does not exist, recursively create all directories until it does.
Definition: shared.cpp:1115
int fc_vsnprintcf(char *buf, size_t buf_len, const char *format, const struct cf_sequence *sequences, size_t sequences_num) fc__attribute((nonnull(1
QFileInfoList find_files_in_path(const QStringList &path, const QString &pattern, bool nodups)
Search for file names matching the pattern in the provided list of directories.
Definition: shared.cpp:681
void randomize_base64url_string(char *s, size_t n)
generate a random string meeting criteria such as is_ascii_name(), is_base64url(),...
Definition: shared.cpp:279
QString freeciv_storage_dir()
Returns string which gives freeciv storage dir.
Definition: shared.cpp:419
void remove_leading_trailing_spaces(char *s)
Removes leading and trailing spaces in string pointed to by 's'.
Definition: shared.cpp:353
const QStringList & get_scenario_dirs()
Returns a list of scenario directory paths, in the order in which they should be searched.
Definition: shared.cpp:594
size_t size
Definition: specvec.h:64
const void * ptr_value
Definition: shared.h:233
const char * str_value
Definition: shared.h:234
int int_value
Definition: shared.h:231
bool bool_value
Definition: shared.h:229
char letter
Definition: shared.h:227
float float_value
Definition: shared.h:232
char char_value
Definition: shared.h:230
enum cf_type type
Definition: shared.h:226
int fc__attribute((nonnull(1, 3)))