1 /*
2 * libzvbi -- Miscellaneous cows and chickens
3 *
4 * Copyright (C) 2000-2003 I�aki Garc�a Etxebarria
5 * Copyright (C) 2002-2007 Michael H. Schimek
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301 USA.
21 */
22
23 /* $Id: misc.h,v 1.24 2013/07/02 02:32:31 mschimek Exp $ */
24
25 #ifndef MISC_H
26 #define MISC_H
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <stddef.h>
31 #include <stdarg.h>
32 #include <string.h>
33 #include <inttypes.h> /* (u)intXX_t */
34 #include <sys/types.h> /* (s)size_t */
35 #include <float.h> /* DBL_MAX */
36 #include <limits.h> /* (S)SIZE_MAX */
37 #include <assert.h>
38
39 #include "macros.h"
40 #include "ccx_common_platform.h"
41 #include "ccx_common_constants.h"
42 #include "ccx_common_structs.h"
43
44 #define N_ELEMENTS(array) (sizeof (array) / sizeof (*(array)))
45
46 #ifdef __GNUC__
47
48 #if __GNUC__ < 3
49 /* Expect expression usually true/false, schedule accordingly. */
50 # define likely(expr) (expr)
51 # define unlikely(expr) (expr)
52 #else
53 # define likely(expr) __builtin_expect(expr, 1)
54 # define unlikely(expr) __builtin_expect(expr, 0)
55 #endif
56
57 #undef __i386__
58 #undef __i686__
59 /* FIXME #cpu is deprecated
60 #if #cpu (i386)
61 # define __i386__ 1
62 #endif
63 #if #cpu (i686)
64 # define __i686__ 1
65 #endif
66 */
67
68 /* &x == PARENT (&x.tm_min, struct tm, tm_min),
69 safer than &x == (struct tm *) &x.tm_min. A NULL _ptr is safe and
70 will return NULL, not -offsetof(_member). */
71 #undef PARENT
72 #define PARENT(_ptr, _type, _member) ({ \
73 __typeof__ (&((_type *) 0)->_member) _p = (_ptr); \
74 (_p != 0) ? (_type *)(((char *) _p) - offsetof (_type, \
75 _member)) : (_type *) 0; \
76 })
77
78 /* Like PARENT(), to be used with const _ptr. */
79 #define CONST_PARENT(_ptr, _type, _member) ({ \
80 __typeof__ (&((const _type *) 0)->_member) _p = (_ptr); \
81 (_p != 0) ? (const _type *)(((const char *) _p) - offsetof \
82 (const _type, _member)) : (const _type *) 0; \
83 })
84
85 /* Note the following macros have no side effects only when you
86 compile with GCC, so don't expect this. */
87
88 /* Absolute value of int, long or long long without a branch.
89 Note ABS (INT_MIN) -> INT_MAX + 1. */
90 #undef ABS
91 #define ABS(n) ({ \
92 register __typeof__ (n) _n = (n), _t = _n; \
93 if (-1 == (-1 >> 1)) { /* do we have signed shifts? */ \
94 _t >>= sizeof (_t) * 8 - 1; \
95 _n ^= _t; \
96 _n -= _t; \
97 } else if (_n < 0) { /* also warns if n is unsigned type */ \
98 _n = -_n; \
99 } \
100 /* return */ _n; \
101 })
102
103 #undef MIN
104 #define MIN(x, y) ({ \
105 __typeof__ (x) _x = (x); \
106 __typeof__ (y) _y = (y); \
107 (void)(&_x == &_y); /* warn if types do not match */ \
108 /* return */ (_x < _y) ? _x : _y; \
109 })
110
111 #undef MAX
112 #define MAX(x, y) ({ \
113 __typeof__ (x) _x = (x); \
114 __typeof__ (y) _y = (y); \
115 (void)(&_x == &_y); /* warn if types do not match */ \
116 /* return */ (_x > _y) ? _x : _y; \
117 })
118
119 /* Note other compilers may swap only int, long or pointer. */
120 #undef SWAP
121 #define SWAP(x, y) \
122 do { \
123 __typeof__ (x) _x = x; \
124 x = y; \
125 y = _x; \
126 } while (0)
127
128 #undef SATURATE
129 #ifdef __i686__ /* has conditional move */
130 #define SATURATE(n, min, max) ({ \
131 __typeof__ (n) _n = (n); \
132 __typeof__ (n) _min = (min); \
133 __typeof__ (n) _max = (max); \
134 (void)(&_n == &_min); /* warn if types do not match */ \
135 (void)(&_n == &_max); \
136 if (_n < _min) \
137 _n = _min; \
138 if (_n > _max) \
139 _n = _max; \
140 /* return */ _n; \
141 })
142 #else
143 #define SATURATE(n, min, max) ({ \
144 __typeof__ (n) _n = (n); \
145 __typeof__ (n) _min = (min); \
146 __typeof__ (n) _max = (max); \
147 (void)(&_n == &_min); /* warn if types do not match */ \
148 (void)(&_n == &_max); \
149 if (_n < _min) \
150 _n = _min; \
151 else if (_n > _max) \
152 _n = _max; \
153 /* return */ _n; \
154 })
155 #endif
156
157 #else /* !__GNUC__ */
158
159 #define likely(expr) (expr)
160 #define unlikely(expr) (expr)
161 #undef __i386__
162 #undef __i686__
163
164 static char *
PARENT_HELPER(char * p,unsigned int offset)165 PARENT_HELPER (char *p, unsigned int offset)
166 { return (0 == p) ? ((char *) 0) : p - offset; }
167
168 static const char *
CONST_PARENT_HELPER(const char * p,unsigned int offset)169 CONST_PARENT_HELPER (const char *p, unsigned int offset)
170 { return (0 == p) ? ((char *) 0) : p - offset; }
171
172 #define PARENT(_ptr, _type, _member) \
173 ((0 == offsetof (_type, _member)) ? (_type *)(_ptr) \
174 : (_type *) PARENT_HELPER ((char *)(_ptr), offsetof (_type, _member)))
175 #define CONST_PARENT(_ptr, _type, _member) \
176 ((0 == offsetof (const _type, _member)) ? (const _type *)(_ptr) \
177 : (const _type *) CONST_PARENT_HELPER ((const char *)(_ptr), \
178 offsetof (const _type, _member)))
179
180 #undef ABS
181 #define ABS(n) (((n) < 0) ? -(n) : (n))
182
183 #undef MIN
184 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
185
186 #undef MAX
187 #define MAX(x, y) (((x) > (y)) ? (x) : (y))
188
189 #undef SWAP
190 #define SWAP(x, y) \
191 do { \
192 long _x = x; \
193 x = y; \
194 y = _x; \
195 } while (0)
196
197 #undef SATURATE
198 #define SATURATE(n, min, max) MIN (MAX (min, n), max)
199
200 #endif /* !__GNUC__ */
201
202 /* 32 bit constant byte reverse, e.g. 0xAABBCCDD -> 0xDDCCBBAA. */
203 #define SWAB32(m) \
204 (+ (((m) & 0xFF000000) >> 24) \
205 + (((m) & 0xFF0000) >> 8) \
206 + (((m) & 0xFF00) << 8) \
207 + (((m) & 0xFF) << 24))
208
209 #ifdef HAVE_BUILTIN_POPCOUNT
210 # define popcnt(x) __builtin_popcount ((uint32_t)(x))
211 #else
212 # define popcnt(x) _vbi_popcnt (x)
213 #endif
214
215 extern unsigned int
216 _vbi_popcnt (uint32_t x);
217
218 /* NB GCC inlines and optimizes these functions when size is const. */
219 #define SET(var) memset (&(var), ~0, sizeof (var))
220
221 #define CLEAR(var) memset (&(var), 0, sizeof (var))
222
223 /* Useful to copy arrays, otherwise use assignment. */
224 #define COPY(d, s) \
225 (assert (sizeof (d) == sizeof (s)), memcpy (d, s, sizeof (d)))
226
227 /* Copy string const into char array. */
228 #define STRACPY(array, s) \
229 do { \
230 /* Complain if s is no string const or won't fit. */ \
231 const char t_[sizeof (array) - 1] _vbi_unused = s; \
232 \
233 memcpy (array, s, sizeof (s)); \
234 } while (0)
235
236 /* Copy bits through mask. */
237 #define COPY_SET_MASK(dest, from, mask) \
238 (dest ^= (from) ^ (dest & (mask)))
239
240 /* Set bits if cond is TRUE, clear if FALSE. */
241 #define COPY_SET_COND(dest, bits, cond) \
242 ((cond) ? (dest |= (bits)) : (dest &= ~(bits)))
243
244 /* Set and clear bits. */
245 #define COPY_SET_CLEAR(dest, set, clear) \
246 (dest = (dest & ~(clear)) | (set))
247
248 /* For applications, debugging and fault injection during unit tests. */
249
250 #define vbi_malloc malloc
251 #define vbi_realloc realloc
252 #define vbi_strdup strdup
253 #define vbi_free free
254
255 #define vbi_cache_malloc vbi_malloc
256 #define vbi_cache_free vbi_free
257
258 /* Helper functions. */
259
260 _vbi_inline int
_vbi_to_ascii(int c)261 _vbi_to_ascii (int c)
262 {
263 if (c < 0)
264 return '?';
265
266 c &= 0x7F;
267
268 if (c < 0x20 || c >= 0x7F)
269 return '.';
270
271 return c;
272 }
273
274 typedef struct {
275 const char * key;
276 int value;
277 } _vbi_key_value_pair;
278
279 extern vbi_bool
280 _vbi_keyword_lookup (int * value,
281 const char ** inout_s,
282 const _vbi_key_value_pair * table,
283 unsigned int n_pairs)
284 _vbi_nonnull ((1, 2, 3));
285
286 extern void
287 _vbi_shrink_vector_capacity (void ** vector,
288 size_t * capacity,
289 size_t min_capacity,
290 size_t element_size)
291 _vbi_nonnull ((1, 2));
292 extern vbi_bool
293 _vbi_grow_vector_capacity (void ** vector,
294 size_t * capacity,
295 size_t min_capacity,
296 size_t element_size)
297 _vbi_nonnull ((1, 2));
298
299 #define debug1 debug
300 #define debug2 debug
301 #define debug3 debug
302 #define warning log
303 #define error log
304 #define info debug
305
306 #define debug(a, fmt, ...) \
307 ccx_common_logging.debug_ftn(CCX_DMT_PARSE, "VBI:%s:%d: "fmt , __FUNCTION__ ,__LINE__ , ##__VA_ARGS__)
308 #define log(a, fmt, ...) \
309 ccx_common_logging.log_ftn("VBI:%d: "fmt , __LINE__ , ##__VA_ARGS__)
310
311 /* Portability stuff. */
312
313 /* These should be defined in inttypes.h. */
314 #ifndef PRId64
315 # define PRId64 "lld"
316 #endif
317 #ifndef PRIu64
318 # define PRIu64 "llu"
319 #endif
320 #ifndef PRIx64
321 # define PRIx64 "llx"
322 #endif
323
324 /* Should be defined in C99 limits.h? */
325 #ifndef SIZE_MAX
326 # define SIZE_MAX ((size_t) -1)
327 #endif
328
329 #ifndef TIME_MIN
330 # define TIME_MIN (_vbi_time_min ())
331 _vbi_inline time_t
_vbi_time_min(void)332 _vbi_time_min (void)
333 {
334 const time_t t = (time_t) -1.25;
335
336 if (t < -1) {
337 return (time_t)((sizeof (time_t) > 4) ? DBL_MIN : FLT_MIN);
338 } else if (t < 0) {
339 return ((uint64_t) 1) << (sizeof (time_t) * 8 - 1);
340 } else {
341 return 0;
342 }
343 }
344 #endif
345
346 #ifndef TIME_MAX
347 # define TIME_MAX (_vbi_time_max ())
348 _vbi_inline time_t
_vbi_time_max(void)349 _vbi_time_max (void)
350 {
351 const time_t t = (time_t) -1.25;
352
353 if (t < -1) {
354 return (time_t)((sizeof (time_t) > 4) ? DBL_MAX : FLT_MAX);
355 } else if (t < 0) {
356 /* Most likely signed 32 or 64 bit. */
357 return (((uint64_t) 1) << (sizeof (time_t) * 8 - 1)) - 1;
358 } else {
359 return -1;
360 }
361 }
362 #endif
363
364 /* __va_copy is a GNU extension. */
365 #ifndef __va_copy
366 # define __va_copy(ap1, ap2) do { ap1 = ap2; } while (0)
367 #endif
368
369 /* Use this instead of strncpy(). strlcpy() is a BSD extension. */
370 #ifndef HAVE_STRLCPY
371 # define strlcpy _vbi_strlcpy
372 #endif
373 #undef strncpy
374 #define strncpy use_strlcpy_instead
375
376 extern size_t
377 _vbi_strlcpy (char * dst,
378 const char * src,
379 size_t size)
380 _vbi_nonnull ((1, 2));
381
382 /* strndup() is a BSD/GNU extension. */
383 #ifndef HAVE_STRNDUP
384 # define strndup _vbi_strndup
385 #endif
386
387 extern char *
388 _vbi_strndup (const char * s,
389 size_t len)
390 _vbi_nonnull ((1));
391
392 /* vasprintf() is a GNU extension. */
393 #ifndef HAVE_VASPRINTF
394 # define vasprintf _vbi_vasprintf
395 #endif
396
397 extern int
398 _vbi_vasprintf (char ** dstp,
399 const char * templ,
400 va_list ap)
401 _vbi_nonnull ((1, 2));
402
403 /* asprintf() is a GNU extension. */
404 #ifndef HAVE_ASPRINTF
405 # define asprintf _vbi_asprintf
406 #endif
407
408 extern int
409 _vbi_asprintf (char ** dstp,
410 const char * templ,
411 ...)
412 _vbi_nonnull ((1, 2)) _vbi_format ((printf, 2, 3));
413
414 #undef sprintf
415 #define sprintf use_snprintf_or_asprintf_instead
416
417 #endif /* MISC_H */
418
419 /*
420 Local variables:
421 c-set-style: K&R
422 c-basic-offset: 8
423 End:
424 */
425