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 "version.h"
41 
42 #define N_ELEMENTS(array) (sizeof (array) / sizeof (*(array)))
43 
44 #ifdef __GNUC__
45 
46 #if __GNUC__ < 3
47 /* Expect expression usually true/false, schedule accordingly. */
48 #  define likely(expr) (expr)
49 #  define unlikely(expr) (expr)
50 #else
51 #  define likely(expr) __builtin_expect(expr, 1)
52 #  define unlikely(expr) __builtin_expect(expr, 0)
53 #endif
54 
55 #undef __i386__
56 #undef __i686__
57 /* FIXME #cpu is deprecated
58 #if defined(__i386__)
59 #  define __i386__ 1
60 #endif
61 #if defined(__i686__)
62 #  define __i686__ 1
63 #endif
64 */
65 
66 /* &x == PARENT (&x.tm_min, struct tm, tm_min),
67    safer than &x == (struct tm *) &x.tm_min. A NULL _ptr is safe and
68    will return NULL, not -offsetof(_member). */
69 #undef PARENT
70 #define PARENT(_ptr, _type, _member) ({					\
71 	__typeof__ (&((_type *) 0)->_member) _p = (_ptr);		\
72 	(_p != 0) ? (_type *)(((char *) _p) - offsetof (_type,		\
73 	  _member)) : (_type *) 0;					\
74 })
75 
76 /* Like PARENT(), to be used with const _ptr. */
77 #define CONST_PARENT(_ptr, _type, _member) ({				\
78 	__typeof__ (&((const _type *) 0)->_member) _p = (_ptr);		\
79 	(_p != 0) ? (const _type *)(((const char *) _p) - offsetof	\
80 	 (const _type, _member)) : (const _type *) 0;			\
81 })
82 
83 /* Note the following macros have no side effects only when you
84    compile with GCC, so don't expect this. */
85 
86 /* Absolute value of int, long or long long without a branch.
87    Note ABS (INT_MIN) -> INT_MAX + 1. */
88 #undef ABS
89 #define ABS(n) ({							\
90 	register __typeof__ (n) _n = (n), _t = _n;			\
91 	if (-1 == (-1 >> 1)) { /* do we have signed shifts? */		\
92 		_t >>= sizeof (_t) * 8 - 1;				\
93 		_n ^= _t;						\
94 		_n -= _t;						\
95 	} else if (_n < 0) { /* also warns if n is unsigned type */	\
96 		_n = -_n;						\
97 	}								\
98 	/* return */ _n;						\
99 })
100 
101 #undef MIN
102 #define MIN(x, y) ({							\
103 	__typeof__ (x) _x = (x);					\
104 	__typeof__ (y) _y = (y);					\
105 	(void)(&_x == &_y); /* warn if types do not match */		\
106 	/* return */ (_x < _y) ? _x : _y;				\
107 })
108 
109 #undef MAX
110 #define MAX(x, y) ({							\
111 	__typeof__ (x) _x = (x);					\
112 	__typeof__ (y) _y = (y);					\
113 	(void)(&_x == &_y); /* warn if types do not match */		\
114 	/* return */ (_x > _y) ? _x : _y;				\
115 })
116 
117 /* Note other compilers may swap only int, long or pointer. */
118 #undef SWAP
119 #define SWAP(x, y)							\
120 do {									\
121 	__typeof__ (x) _x = x;						\
122 	x = y;								\
123 	y = _x;								\
124 } while (0)
125 
126 #undef SATURATE
127 #ifdef __i686__ /* has conditional move */
128 #define SATURATE(n, min, max) ({					\
129 	__typeof__ (n) _n = (n);					\
130 	__typeof__ (n) _min = (min);					\
131 	__typeof__ (n) _max = (max);					\
132 	(void)(&_n == &_min); /* warn if types do not match */		\
133 	(void)(&_n == &_max);						\
134 	if (_n < _min)							\
135 		_n = _min;						\
136 	if (_n > _max)							\
137 		_n = _max;						\
138 	/* return */ _n;						\
139 })
140 #else
141 #define SATURATE(n, min, max) ({					\
142 	__typeof__ (n) _n = (n);					\
143 	__typeof__ (n) _min = (min);					\
144 	__typeof__ (n) _max = (max);					\
145 	(void)(&_n == &_min); /* warn if types do not match */		\
146 	(void)(&_n == &_max);						\
147 	if (_n < _min)							\
148 		_n = _min;						\
149 	else if (_n > _max)						\
150 		_n = _max;						\
151 	/* return */ _n;						\
152 })
153 #endif
154 
155 #else /* !__GNUC__ */
156 
157 #define likely(expr) (expr)
158 #define unlikely(expr) (expr)
159 #undef __i386__
160 #undef __i686__
161 
162 static char *
PARENT_HELPER(char * p,unsigned int offset)163 PARENT_HELPER (char *p, unsigned int offset)
164 { return (0 == p) ? ((char *) 0) : p - offset; }
165 
166 static const char *
CONST_PARENT_HELPER(const char * p,unsigned int offset)167 CONST_PARENT_HELPER (const char *p, unsigned int offset)
168 { return (0 == p) ? ((char *) 0) : p - offset; }
169 
170 #define PARENT(_ptr, _type, _member)					\
171 	((0 == offsetof (_type, _member)) ? (_type *)(_ptr)		\
172 	 : (_type *) PARENT_HELPER ((char *)(_ptr), offsetof (_type, _member)))
173 #define CONST_PARENT(_ptr, _type, _member)				\
174 	((0 == offsetof (const _type, _member)) ? (const _type *)(_ptr)	\
175 	 : (const _type *) CONST_PARENT_HELPER ((const char *)(_ptr),	\
176 	  offsetof (const _type, _member)))
177 
178 #undef ABS
179 #define ABS(n) (((n) < 0) ? -(n) : (n))
180 
181 #undef MIN
182 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
183 
184 #undef MAX
185 #define MAX(x, y) (((x) > (y)) ? (x) : (y))
186 
187 #undef SWAP
188 #define SWAP(x, y)							\
189 do {									\
190 	long _x = x;							\
191 	x = y;								\
192 	y = _x;								\
193 } while (0)
194 
195 #undef SATURATE
196 #define SATURATE(n, min, max) MIN (MAX (min, n), max)
197 
198 #endif /* !__GNUC__ */
199 
200 /* 32 bit constant byte reverse, e.g. 0xAABBCCDD -> 0xDDCCBBAA. */
201 #define SWAB32(m)							\
202 	(+ (((m) & 0xFF000000) >> 24)					\
203 	 + (((m) & 0xFF0000) >> 8)					\
204 	 + (((m) & 0xFF00) << 8)					\
205 	 + (((m) & 0xFF) << 24))
206 
207 #ifdef HAVE_BUILTIN_POPCOUNT
208 #  define popcnt(x) __builtin_popcount ((uint32_t)(x))
209 #else
210 #  define popcnt(x) _vbi_popcnt (x)
211 #endif
212 
213 extern unsigned int
214 _vbi_popcnt			(uint32_t		x);
215 
216 /* NB GCC inlines and optimizes these functions when size is const. */
217 #define SET(var) memset (&(var), ~0, sizeof (var))
218 
219 #define CLEAR(var) memset (&(var), 0, sizeof (var))
220 
221 /* Useful to copy arrays, otherwise use assignment. */
222 #define COPY(d, s)							\
223 	(assert (sizeof (d) == sizeof (s)), memcpy (d, s, sizeof (d)))
224 
225 /* Copy string const into char array. */
226 #define STRACPY(array, s)						\
227 do {									\
228 	/* Complain if s is no string const or won't fit. */		\
229 	const char t_[sizeof (array) - 1] _vbi_unused = s;		\
230 									\
231 	memcpy (array, s, sizeof (s));					\
232 } while (0)
233 
234 /* Copy bits through mask. */
235 #define COPY_SET_MASK(dest, from, mask)					\
236 	(dest ^= (from) ^ (dest & (mask)))
237 
238 /* Set bits if cond is TRUE, clear if FALSE. */
239 #define COPY_SET_COND(dest, bits, cond)					\
240 	 ((cond) ? (dest |= (bits)) : (dest &= ~(bits)))
241 
242 /* Set and clear bits. */
243 #define COPY_SET_CLEAR(dest, set, clear)				\
244 	(dest = (dest & ~(clear)) | (set))
245 
246 /* For applications, debugging and fault injection during unit tests. */
247 
248 #if 2 == VBI_VERSION_MINOR
249 #  define vbi_malloc malloc
250 #  define vbi_realloc realloc
251 #  define vbi_strdup strdup
252 #  define vbi_free free
253 #else
254 
255 extern void *
256 (* vbi_malloc)			(size_t);
257 extern void *
258 (* vbi_realloc)		(void *,
259 				 size_t)
260   _vbi_nonnull ((1));
261 extern char *
262 (* vbi_strdup)			(const char *)
263   _vbi_nonnull ((1));
264 extern void
265 (* vbi_free)			(void *);
266 
267 #endif
268 
269 #define vbi_cache_malloc vbi_malloc
270 #define vbi_cache_free vbi_free
271 
272 /* Helper functions. */
273 
274 _vbi_inline int
_vbi_to_ascii(int c)275 _vbi_to_ascii			(int			c)
276 {
277 	if (c < 0)
278 		return '?';
279 
280 	c &= 0x7F;
281 
282 	if (c < 0x20 || c >= 0x7F)
283 		return '.';
284 
285 	return c;
286 }
287 
288 typedef struct {
289 	const char *		key;
290 	int			value;
291 } _vbi_key_value_pair;
292 
293 extern vbi_bool
294 _vbi_keyword_lookup		(int *			value,
295 				 const char **		inout_s,
296 				 const _vbi_key_value_pair * table,
297 				 unsigned int		n_pairs)
298   _vbi_nonnull ((1, 2, 3));
299 
300 extern void
301 _vbi_shrink_vector_capacity	(void **		vector,
302 				 size_t *		capacity,
303 				 size_t			min_capacity,
304 				 size_t			element_size)
305   _vbi_nonnull ((1, 2));
306 extern vbi_bool
307 _vbi_grow_vector_capacity	(void **		vector,
308 				 size_t *		capacity,
309 				 size_t			min_capacity,
310 				 size_t			element_size)
311   _vbi_nonnull ((1, 2));
312 
313 /* Logging stuff. */
314 
315 extern _vbi_log_hook		_vbi_global_log;
316 
317 extern void
318 _vbi_log_vprintf		(vbi_log_fn *		log_fn,
319 				 void *			user_data,
320 				 vbi_log_mask		level,
321 				 const char *		source_file,
322 				 const char *		context,
323 				 const char *		templ,
324 				 va_list		ap)
325   _vbi_nonnull ((1, 4, 5, 6));
326 extern void
327 _vbi_log_printf		(vbi_log_fn *		log_fn,
328 				 void *			user_data,
329 				 vbi_log_mask		level,
330 				 const char *		source_file,
331 				 const char *		context,
332 				 const char *		templ,
333 				 ...)
334   _vbi_nonnull ((1, 4, 5, 6)) _vbi_format ((printf, 6, 7));
335 
336 #define _vbi_log(hook, level, templ, args...)				\
337 do {									\
338 	_vbi_log_hook *_h = hook;					\
339 									\
340 	if ((NULL != _h && 0 != (_h->mask & level))			\
341 	    || (_h = &_vbi_global_log, 0 != (_h->mask & level)))	\
342 		_vbi_log_printf (_h->fn, _h->user_data,		\
343 				  level, __FILE__, __FUNCTION__,	\
344 				  templ , ##args);			\
345 } while (0)
346 
347 #define _vbi_vlog(hook, level, templ, ap)				\
348 do {									\
349 	_vbi_log_hook *_h = hook;					\
350 									\
351 	if ((NULL != _h && 0 != (_h->mask & level))			\
352 	    || (_h = &_vbi_global_log, 0 != (_h->mask & level)))	\
353 		_vbi_log_vprintf (_h->fn, _h->user_data,		\
354 				  level, __FILE__, __FUNCTION__,	\
355 				  templ, ap);				\
356 } while (0)
357 
358 #define error(hook, templ, args...)					\
359 	_vbi_log (hook, VBI_LOG_ERROR, templ , ##args)
360 #define warning(hook, templ, args...)					\
361 	_vbi_log (hook, VBI_LOG_ERROR, templ , ##args)
362 #define notice(hook, templ, args...)					\
363 	_vbi_log (hook, VBI_LOG_NOTICE, templ , ##args)
364 #define info(hook, templ, args...)					\
365 	_vbi_log (hook, VBI_LOG_INFO, templ , ##args)
366 #define debug1(hook, templ, args...)					\
367 	_vbi_log (hook, VBI_LOG_DEBUG, templ , ##args)
368 #define debug2(hook, templ, args...)					\
369 	_vbi_log (hook, VBI_LOG_DEBUG2, templ , ##args)
370 #define debug3(hook, templ, args...)					\
371 	_vbi_log (hook, VBI_LOG_DEBUG3, templ , ##args)
372 
373 /* Portability stuff. */
374 
375 /* These should be defined in inttypes.h. */
376 #ifndef PRId64
377 #  define PRId64 "lld"
378 #endif
379 #ifndef PRIu64
380 #  define PRIu64 "llu"
381 #endif
382 #ifndef PRIx64
383 #  define PRIx64 "llx"
384 #endif
385 
386 /* Should be defined in C99 limits.h? */
387 #ifndef SIZE_MAX
388 #  define SIZE_MAX ((size_t) -1)
389 #endif
390 
391 #ifndef TIME_MIN
392 #  define TIME_MIN (_vbi_time_min ())
393 _vbi_inline time_t
_vbi_time_min(void)394 _vbi_time_min			(void)
395 {
396 	const time_t t = (time_t) -1.25;
397 
398 	if (t < -1) {
399 		return (time_t)((sizeof (time_t) > 4) ? DBL_MIN : FLT_MIN);
400 	} else if (t < 0) {
401 		return ((uint64_t) 1) << (sizeof (time_t) * 8 - 1);
402 	} else {
403 		return 0;
404 	}
405 }
406 #endif
407 
408 #ifndef TIME_MAX
409 #  define TIME_MAX (_vbi_time_max ())
410 _vbi_inline time_t
_vbi_time_max(void)411 _vbi_time_max			(void)
412 {
413 	const time_t t = (time_t) -1.25;
414 
415 	if (t < -1) {
416 		return (time_t)((sizeof (time_t) > 4) ? DBL_MAX : FLT_MAX);
417 	} else if (t < 0) {
418 		/* Most likely signed 32 or 64 bit. */
419 		return (((uint64_t) 1) << (sizeof (time_t) * 8 - 1)) - 1;
420 	} else {
421 		return -1;
422 	}
423 }
424 #endif
425 
426 /* __va_copy is a GNU extension. */
427 #ifndef __va_copy
428 #  define __va_copy(ap1, ap2) do { ap1 = ap2; } while (0)
429 #endif
430 
431 /* Use this instead of strncpy(). strlcpy() is a BSD extension. */
432 #ifndef HAVE_STRLCPY
433 #  define strlcpy _vbi_strlcpy
434 #endif
435 #undef strncpy
436 #define strncpy use_strlcpy_instead
437 
438 extern size_t
439 _vbi_strlcpy			(char *			dst,
440 				 const char *		src,
441 				 size_t			size)
442   _vbi_nonnull ((1, 2));
443 
444 /* strndup() is a BSD/GNU extension. */
445 #ifndef HAVE_STRNDUP
446 #  define strndup _vbi_strndup
447 #endif
448 
449 extern char *
450 _vbi_strndup			(const char *		s,
451 				 size_t			len)
452   _vbi_nonnull ((1));
453 
454 /* vasprintf() is a GNU extension. */
455 #ifndef HAVE_VASPRINTF
456 #  define vasprintf _vbi_vasprintf
457 #endif
458 
459 extern int
460 _vbi_vasprintf			(char **		dstp,
461 				 const char *		templ,
462 				 va_list		ap)
463   _vbi_nonnull ((1, 2));
464 
465 /* asprintf() is a GNU extension. */
466 #ifndef HAVE_ASPRINTF
467 #  define asprintf _vbi_asprintf
468 #endif
469 
470 extern int
471 _vbi_asprintf			(char **		dstp,
472 				 const char *		templ,
473 				 ...)
474   _vbi_nonnull ((1, 2)) _vbi_format ((printf, 2, 3));
475 
476 #undef sprintf
477 #define sprintf use_snprintf_or_asprintf_instead
478 
479 #endif /* MISC_H */
480 
481 /*
482 Local variables:
483 c-set-style: K&R
484 c-basic-offset: 8
485 End:
486 */
487