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