table.c: Fix a coverity warning of uninitialized value 'dummy'
[platform/upstream/libxkbcommon.git] / src / utils.h
1 /*
2  * Copyright © 2012 Ran Benita <ran234@gmail.com>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23
24 #ifndef UTILS_H
25 #define UTILS_H 1
26
27 #include <errno.h>
28 #include <inttypes.h>
29 #include <stdarg.h>
30 #include <stdbool.h>
31 #include <stdio.h>
32 #include <string.h>
33 #if HAVE_UNISTD_H
34 # include <unistd.h>
35 #else
36 /* Required on Windows where unistd.h doesn't exist */
37 # define R_OK    4               /* Test for read permission.  */
38 # define W_OK    2               /* Test for write permission.  */
39 # define X_OK    1               /* Test for execute permission.  */
40 # define F_OK    0               /* Test for existence.  */
41 #endif
42
43 #ifdef _WIN32
44 # include <direct.h>
45 # include <io.h>
46 # ifndef S_ISDIR
47 #  define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
48 # endif
49 #endif
50
51 #include "darray.h"
52
53 #define STATIC_ASSERT(expr, message) do { \
54     switch (0) { case 0: case (expr): ; } \
55 } while (0)
56
57 #define ARRAY_SIZE(arr) ((sizeof(arr) / sizeof(*(arr))))
58
59 #define MIN(a, b) ((a) < (b) ? (a) : (b))
60 #define MAX(a, b) ((a) > (b) ? (a) : (b))
61
62 /* Round up @a so it's divisible by @b. */
63 #define ROUNDUP(a, b) (((a) + (b) - 1) / (b) * (b))
64
65 #define STRINGIFY(x) #x
66 #define STRINGIFY2(x) STRINGIFY(x)
67
68 /* Check if a character is valid in a string literal */
69 static inline bool
70 is_valid_char(char c)
71 {
72     /* Currently we only check for NULL character, but this could be extended
73      * in the future to further ASCII control characters. */
74     return c != 0;
75 }
76
77 char
78 to_lower(char c);
79
80 int
81 istrcmp(const char *a, const char *b);
82
83 int
84 istrncmp(const char *a, const char *b, size_t n);
85
86 static inline bool
87 streq(const char *s1, const char *s2)
88 {
89     assert(s1 && s2);
90     return strcmp(s1, s2) == 0;
91 }
92
93 static inline bool
94 streq_null(const char *s1, const char *s2)
95 {
96     if (s1 == NULL || s2 == NULL)
97         return s1 == s2;
98     return streq(s1, s2);
99 }
100
101 static inline bool
102 streq_not_null(const char *s1, const char *s2)
103 {
104     if (!s1 || !s2)
105         return false;
106     return streq(s1, s2);
107 }
108
109 static inline bool
110 istreq(const char *s1, const char *s2)
111 {
112     return istrcmp(s1, s2) == 0;
113 }
114
115 static inline bool
116 istreq_prefix(const char *s1, const char *s2)
117 {
118     return istrncmp(s1, s2, strlen(s1)) == 0;
119 }
120
121 static inline char *
122 strdup_safe(const char *s)
123 {
124     return s ? strdup(s) : NULL;
125 }
126
127 static inline size_t
128 strlen_safe(const char *s)
129 {
130     return s ? strlen(s) : 0;
131 }
132
133 static inline bool
134 isempty(const char *s)
135 {
136     return s == NULL || s[0] == '\0';
137 }
138
139 static inline const char *
140 strnull(const char *s)
141 {
142     return s ? s : "(null)";
143 }
144
145 static inline const char *
146 strempty(const char *s)
147 {
148     return s ? s : "";
149 }
150
151 static inline void *
152 memdup(const void *mem, size_t nmemb, size_t size)
153 {
154     void *p = calloc(nmemb, size);
155     if (p)
156         memcpy(p, mem, nmemb * size);
157     return p;
158 }
159
160 #if !(defined(HAVE_STRNDUP) && HAVE_STRNDUP)
161 static inline char *
162 strndup(const char *s, size_t n)
163 {
164     size_t slen = strlen(s);
165     size_t len = MIN(slen, n);
166     char *p = malloc(len + 1);
167     if (!p)
168         return NULL;
169     memcpy(p, s, len);
170     p[len] = '\0';
171     return p;
172 }
173 #endif
174
175 /* ctype.h is locale-dependent and has other oddities. */
176 static inline bool
177 is_space(char ch)
178 {
179     return ch == ' ' || (ch >= '\t' && ch <= '\r');
180 }
181
182 static inline bool
183 is_alpha(char ch)
184 {
185     return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
186 }
187
188 static inline bool
189 is_digit(char ch)
190 {
191     return ch >= '0' && ch <= '9';
192 }
193
194 static inline bool
195 is_alnum(char ch)
196 {
197     return is_alpha(ch) || is_digit(ch);
198 }
199
200 static inline bool
201 is_xdigit(char ch)
202 {
203     return
204         (ch >= '0' && ch <= '9') ||
205         (ch >= 'a' && ch <= 'f') ||
206         (ch >= 'A' && ch <= 'F');
207 }
208
209 static inline bool
210 is_graph(char ch)
211 {
212     /* See table in ascii(7). */
213     return ch >= '!' && ch <= '~';
214 }
215
216 /*
217  * Return the bit position of the most significant bit.
218  * Note: this is 1-based! It's more useful this way, and returns 0 when
219  * mask is all 0s.
220  */
221 static inline unsigned
222 msb_pos(uint32_t mask)
223 {
224     unsigned pos = 0;
225     while (mask) {
226         pos++;
227         mask >>= 1u;
228     }
229     return pos;
230 }
231
232 static inline int
233 one_bit_set(uint32_t x)
234 {
235     return x && (x & (x - 1)) == 0;
236 }
237
238 bool
239 map_file(FILE *file, char **string_out, size_t *size_out);
240
241 void
242 unmap_file(char *string, size_t size);
243
244 static inline bool
245 check_eaccess(const char *path, int mode)
246 {
247 #if defined(HAVE_EACCESS)
248     if (eaccess(path, mode) != 0)
249         return false;
250 #elif defined(HAVE_EUIDACCESS)
251     if (euidaccess(path, mode) != 0)
252         return false;
253 #endif
254
255     return true;
256 }
257
258 #if defined(HAVE_SECURE_GETENV)
259 # define secure_getenv secure_getenv
260 #elif defined(HAVE___SECURE_GETENV)
261 # define secure_getenv __secure_getenv
262 #else
263 # define secure_getenv getenv
264 #endif
265
266 #if defined(HAVE___BUILTIN_EXPECT)
267 # define likely(x)   __builtin_expect(!!(x), 1)
268 # define unlikely(x) __builtin_expect(!!(x), 0)
269 #else
270 # define likely(x)   (x)
271 # define unlikely(x) (x)
272 #endif
273
274 /* Compiler Attributes */
275
276 #if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__CYGWIN__)
277 # define XKB_EXPORT      __attribute__((visibility("default")))
278 #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
279 # define XKB_EXPORT      __global
280 #else /* not gcc >= 4 and not Sun Studio >= 8 */
281 # define XKB_EXPORT
282 #endif
283
284 #if defined(__MINGW32__)
285 # define ATTR_PRINTF(x,y) __attribute__((__format__(__MINGW_PRINTF_FORMAT, x, y)))
286 #elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203)
287 # define ATTR_PRINTF(x,y) __attribute__((__format__(__printf__, x, y)))
288 #else /* not gcc >= 2.3 */
289 # define ATTR_PRINTF(x,y)
290 #endif
291
292 #if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)) \
293     || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
294 # define ATTR_NORETURN __attribute__((__noreturn__))
295 #else
296 # define ATTR_NORETURN
297 #endif /* GNUC  */
298
299 #if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 296)
300 #define ATTR_MALLOC  __attribute__((__malloc__))
301 #else
302 #define ATTR_MALLOC
303 #endif
304
305 #if defined(__GNUC__) && (__GNUC__ >= 4)
306 # define ATTR_NULL_SENTINEL __attribute__((__sentinel__))
307 #else
308 # define ATTR_NULL_SENTINEL
309 #endif /* GNUC >= 4 */
310
311 #if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 295)
312 #define ATTR_PACKED  __attribute__((__packed__))
313 #else
314 #define ATTR_PACKED
315 #endif
316
317 #if !(defined(HAVE_ASPRINTF) && HAVE_ASPRINTF)
318 int asprintf(char **strp, const char *fmt, ...) ATTR_PRINTF(2, 3);
319 # if !(defined(HAVE_VASPRINTF) && HAVE_VASPRINTF)
320 #  include <stdarg.h>
321 int vasprintf(char **strp, const char *fmt, va_list ap);
322 # endif /* !HAVE_VASPRINTF */
323 #endif /* !HAVE_ASPRINTF */
324
325 static inline bool
326 ATTR_PRINTF(3, 4)
327 snprintf_safe(char *buf, size_t sz, const char *format, ...)
328 {
329     va_list ap;
330     int rc;
331
332     va_start(ap, format);
333     rc = vsnprintf(buf, sz, format, ap);
334     va_end(ap);
335
336     return rc >= 0 && (size_t)rc < sz;
337 }
338
339 static inline char *
340 ATTR_PRINTF(1, 0)
341 vasprintf_safe(const char *fmt, va_list args)
342 {
343     char *str;
344     int len;
345
346     len = vasprintf(&str, fmt, args);
347
348     if (len == -1)
349         return NULL;
350
351     return str;
352 }
353
354 /**
355  * A version of asprintf that returns the allocated string or NULL on error.
356  */
357 static inline char *
358 ATTR_PRINTF(1, 2)
359 asprintf_safe(const char *fmt, ...)
360 {
361     va_list args;
362     char *str;
363
364     va_start(args, fmt);
365     str = vasprintf_safe(fmt, args);
366     va_end(args);
367
368     return str;
369 }
370
371 #endif /* UTILS_H */