1 /* $Id: common.h,v 1.16 2010/02/18 01:23:20 fredette Exp $ */
2 
3 /* tme/common.h - header file for common things: */
4 
5 /*
6  * Copyright (c) 2002, 2003 Matt Fredette
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *      This product includes software developed by Matt Fredette.
20  * 4. The name of the author may not be used to endorse or promote products
21  *    derived from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
27  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 #ifndef _TME_COMMON_H
37 #define _TME_COMMON_H
38 
39 /* includes: */
40 #include <assert.h>
41 #include <unistd.h>
42 #include <tmeconfig.h>
43 #ifdef _TME_IMPL
44 #ifdef HAVE_CONFIG_H
45 #include <config.h>
46 #endif /* HAVE_CONFIG_H */
47 #endif /* _TME_IMPL */
48 #include <sys/types.h>
49 
50 /* netinet/in.h is needed to get the hton and ntoh functions: */
51 #include <netinet/in.h>
52 
53 #ifdef _TME_HAVE_SYS_BSWAP_H
54 /* sys/bswap.h is needed for the bswap functions: */
55 #include <sys/bswap.h>
56 #endif /* _TME_HAVE_SYS_BSWAP_H */
57 
58 /* macros: */
59 #undef FALSE
60 #undef TRUE
61 #define FALSE (0)
62 #define TRUE (!FALSE)
63 
64 /* RCS IDs: */
65 #ifdef notyet
66 #define _TME_RCSID(x) static const char _tme_rcsid[] = x
67 _TME_RCSID("$Id: common.h,v 1.16 2010/02/18 01:23:20 fredette Exp $");
68 #else  /* !_TME_IMPL */
69 #define _TME_RCSID(x)
70 #endif /* !_TME_IMPL */
71 
72 /* concatenation: */
73 #if ((defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus)) && !defined(UNIXCPP)) || defined(ANSICPP)
74 #define __TME_CONCAT(a,b) a ## b
75 #define _TME_CONCAT(a,b) __TME_CONCAT(a,b)
76 #else
77 #define _TME_CONCAT(a,b) a/**/b
78 #endif
79 #define _TME_CONCAT5(a,b,c,d,e) _TME_CONCAT(a,_TME_CONCAT(b,_TME_CONCAT(c,_TME_CONCAT(d,e))))
80 #define _TME_CONCAT4(a,b,c,d) _TME_CONCAT(a,_TME_CONCAT(b,_TME_CONCAT(c,d)))
81 #define _TME_CONCAT3(a,b,c) _TME_CONCAT(a,_TME_CONCAT(b,c))
82 
83 /* prototypes: */
84 #if defined(__STDC__) || defined(__cplusplus)
85 #define _TME_P(x) x
86 #else  /* !__STDC__ && !__cplusplus */
87 #define _TME_P(x) ()
88 #endif /* !__STDC__ && !__cplusplus */
89 
90 /* const, inline, and volatile: */
91 #if defined(_TME_IMPL) || defined(__STDC__) || defined(__cplusplus)
92 #define _tme_const const
93 #define _tme_inline inline
94 #define _tme_volatile volatile
95 #else  /* !_TME_IMPL && !__STDC__ && !__cplusplus */
96 #define _tme_const
97 #define _tme_inline
98 #define _tme_volatile
99 #endif /* !_TME_IMPL && !__STDC__ && !__cplusplus */
100 
101 /* bits: */
102 #define _TME_BIT(t, x)		(((t) 1) << (x))
103 #define TME_BIT(x)		_TME_BIT(unsigned int, x)
104 
105 /* alignment: */
106 #define TME_ALIGN(x, y)		(((x) + ((y) - 1)) & -(y))
107 #define TME_ALIGN_MAX		(8)
108 
109 /* endianness: */
110 #define TME_ENDIAN_LITTLE	(0)
111 #define TME_ENDIAN_BIG		(1)
112 #ifdef _TME_WORDS_BIGENDIAN
113 #define TME_ENDIAN_NATIVE TME_ENDIAN_BIG
114 #else  /* !_TME_WORDS_BIGENDIAN */
115 #define TME_ENDIAN_NATIVE TME_ENDIAN_LITTLE
116 #endif /* !_TME_WORDS_BIGENDIAN */
117 
118 /* cast auditing: */
119 #ifndef TME_NO_AUDIT_CASTS
120 #define _tme_audit_type(e, t)	(1 ? (e) : ((t) 0))
121 #else  /* TME_NO_AUDIT_CASTS */
122 #define _tme_audit_type(e, t)	(e)
123 #endif /* TME_AUDIT_CASTS */
124 
125 /* branch prediction: */
126 #if defined(__GNUC__) && ((__GNUC__ == 2 && __GNUC_MINOR__ >= 96) || (__GNUC__ >= 3))
127 #define __tme_predict_true(e)	(__builtin_expect(((e) != 0), 1))
128 #define __tme_predict_false(e)	(__builtin_expect(((e) != 0), 0))
129 #endif /* __GNUC__ >= 2.96 */
130 #ifndef __tme_predict_true
131 #define __tme_predict_true(e)	(e)
132 #endif  /* !__tme_predict_true */
133 #ifndef __tme_predict_false
134 #define __tme_predict_false(e)	(e)
135 #endif /* !__tme_predict_false */
136 
137 /* memory allocation: */
138 #define tme_new(t, x)		((t *) tme_malloc(sizeof(t) * (x)))
139 #define tme_new0(t, x)		((t *) tme_malloc0(sizeof(t) * (x)))
140 #define tme_renew(t, m, x)	((t *) tme_realloc(m, sizeof(t) * (x)))
141 #define tme_dup(t, m, x)	((t *) tme_memdup(m, sizeof(t) * (x)))
142 
143 /* minimum/maximum: */
144 #define TME_MIN(a, b)		(((a) < (b)) ? (a) : (b))
145 #define TME_MAX(a, b)		(((a) > (b)) ? (a) : (b))
146 
147 /* shifts: */
148 /* NB: count is evaluated multiple times and must be greater than
149    zero: */
150 #define TME_SHIFT(type, value, shift, count)	\
151   ((type)					\
152    ((((type) (value))				\
153      shift TME_MIN((count) - 1,			\
154 		   (sizeof(type) * 8) - 1))	\
155     shift 1))
156 
157 /* sign extension: */
158 #define TME_EXT_S8_S16(x)	((tme_int16_t) _tme_audit_type(x, tme_int8_t))
159 #define TME_EXT_S8_S32(x)	((tme_int32_t) _tme_audit_type(x, tme_int8_t))
160 #define TME_EXT_S16_S32(x)	((tme_int32_t) _tme_audit_type(x, tme_int16_t))
161 #define TME_EXT_S8_U16(x)	((tme_uint16_t) TME_EXT_S8_S16(x))
162 #define TME_EXT_S8_U32(x)	((tme_uint32_t) TME_EXT_S8_S32(x))
163 #define TME_EXT_S16_U32(x)	((tme_uint32_t) TME_EXT_S16_S32(x))
164 
165 /* bitfields: */
166 #define _TME_FIELD_EXTRACTU(t, v, s, l) ((((t) (v)) >> (s)) & (_TME_BIT(t, l) - 1))
167 #define TME_FIELD_EXTRACTU(v, s, l) _TME_FIELD_EXTRACTU(unsigned int, v, s, l)
168 #define _TME_FIELD_DEPOSIT(t, v, s, l, x) ((v) = (((v) & ~((_TME_BIT(t, l) - 1) << (s))) | ((x) << (s))))
169 #define TME_FIELD_DEPOSIT8(v, s, l, x) _TME_FIELD_DEPOSIT(tme_uint8_t, v, s, l, x)
170 #define TME_FIELD_DEPOSIT16(v, s, l, x) _TME_FIELD_DEPOSIT(tme_uint16_t, v, s, l, x)
171 #define TME_FIELD_DEPOSIT32(v, s, l, x) _TME_FIELD_DEPOSIT(tme_uint32_t, v, s, l, x)
172 #define _TME_FIELD_MASK_FACTOR(m) (((m) | ((m) << 1)) ^ ((m) << 1))
173 #define TME_FIELD_MASK_EXTRACTU(v, m) (((v) & (m)) / _TME_FIELD_MASK_FACTOR(m))
174 #define TME_FIELD_MASK_DEPOSITU(v, m, x) ((v) = (((v) & ~(m)) | (((x) * _TME_FIELD_MASK_FACTOR(m)) & (m))))
175 #define _TME_FIELD_MASK_MSBIT(m) (((m) | ((m) >> 1)) ^ ((m) >> 1))
176 #define TME_FIELD_MASK_EXTRACTS(v, m)  ((TME_FIELD_MASK_EXTRACTU(v, m) ^ _TME_FIELD_MASK_MSBIT(m)) + (0 - _TME_FIELD_MASK_MSBIT(m)))
177 
178 /* byteswapping: */
179 #ifndef _TME_WORDS_BIGENDIAN
180 #define tme_bswap_u16(x) ((tme_uint16_t) htons((tme_uint16_t) (x)))
181 #define tme_bswap_u32(x) ((tme_uint32_t) htonl((tme_uint32_t) (x)))
182 #else  /* _TME_WORDS_BIGENDIAN */
183 #ifdef _TME_HAVE_BSWAP16
184 #define tme_bswap_u16(x) ((tme_uint16_t) bswap16((tme_uint16_t) (x)))
185 #else  /* !_TME_HAVE_BSWAP16 */
186 static _tme_inline tme_uint16_t
tme_bswap_u16(tme_uint16_t x)187 tme_bswap_u16(tme_uint16_t x)
188 {
189   return ((((x) & 0xff00) >> 8)
190 	  | (((x) & 0x00ff) << 8));
191 }
192 #endif /* !_TME_HAVE_BSWAP16 */
193 #ifdef _TME_HAVE_BSWAP32
194 #define tme_bswap_u32(x) ((tme_uint32_t) bswap32((tme_uint32_t) (x)))
195 #else  /* !_TME_HAVE_BSWAP32 */
196 static _tme_inline tme_uint32_t
tme_bswap_u32(tme_uint32_t x)197 tme_bswap_u32(tme_uint32_t x)
198 {
199   return ((((x) & 0xff000000) >> 24)
200 	  | (((x) & 0x00ff0000) >> 8)
201 	  | (((x) & 0x0000ff00) << 8)
202 	  | (((x) & 0x000000ff) << 24));
203 }
204 #endif /* !_TME_HAVE_BSWAP32 */
205 #endif /* _TME_WORDS_BIGENDIAN */
206 
207 /* endian conversion: */
208 #ifndef _TME_WORDS_BIGENDIAN
209 #define tme_htobe_u16(x) tme_bswap_u16(x)
210 #define tme_htobe_u32(x) tme_bswap_u32(x)
211 #define tme_htobe_u64(x) tme_bswap_u64(x)
212 #define tme_htole_u16(x) (x)
213 #define tme_htole_u32(x) (x)
214 #define tme_htole_u64(x) (x)
215 #else  /* _TME_WORDS_BIGENDIAN */
216 #define tme_htobe_u16(x) (x)
217 #define tme_htobe_u32(x) (x)
218 #define tme_htobe_u64(x) (x)
219 #define tme_htole_u16(x) tme_bswap_u16(x)
220 #define tme_htole_u32(x) tme_bswap_u32(x)
221 #define tme_htole_u64(x) tme_bswap_u64(x)
222 #endif /* _TME_WORDS_BIGENDIAN */
223 #define tme_betoh_u16(x) tme_htobe_u16(x)
224 #define tme_betoh_u32(x) tme_htobe_u32(x)
225 #define tme_betoh_u64(x) tme_htobe_u64(x)
226 #define tme_letoh_u16(x) tme_htole_u16(x)
227 #define tme_letoh_u32(x) tme_htole_u32(x)
228 #define tme_letoh_u64(x) tme_htole_u64(x)
229 
230 /* i18n: */
231 #define _(x) x
232 
233 /* 64-bit values: */
234 #ifndef TME_HAVE_INT64_T
235 
236 /* gcc has a `long long' type that is defined to be twice as long as
237    an int: */
238 /* XXX when exactly did this feature appear? */
239 #if defined(__GNUC__) && (__GNUC__ >= 2) && (_TME_SIZEOF_INT == 4)
240 #define TME_HAVE_INT64_T
241 #define _TME_ALIGNOF_INT64_T _TME_ALIGNOF_INT32_T
242 #define _TME_SHIFTMAX_INT64_T (63)
243 #define _TME_PRI64 "ll"
244 typedef signed long long int tme_int64_t;
245 typedef unsigned long long int tme_uint64_t;
246 #endif /* __GNUC__ && __GNUC__ >= 2 */
247 
248 #endif /* TME_HAVE_INT64_T */
249 union tme_value64 {
250 #ifdef TME_HAVE_INT64_T
251   tme_int64_t tme_value64_int;
252   tme_uint64_t tme_value64_uint;
253 #endif /* TME_HAVE_INT64_T */
254   tme_int32_t tme_value64_int32s[2];
255   tme_uint32_t tme_value64_uint32s[2];
256 #ifndef _TME_WORDS_BIGENDIAN
257 #define tme_value64_int32_lo tme_value64_int32s[0]
258 #define tme_value64_int32_hi tme_value64_int32s[1]
259 #define tme_value64_uint32_lo tme_value64_uint32s[0]
260 #define tme_value64_uint32_hi tme_value64_uint32s[1]
261 #else  /* _TME_WORDS_BIGENDIAN */
262 #define tme_value64_int32_lo tme_value64_int32s[1]
263 #define tme_value64_int32_hi tme_value64_int32s[0]
264 #define tme_value64_uint32_lo tme_value64_uint32s[1]
265 #define tme_value64_uint32_hi tme_value64_uint32s[0]
266 #endif /* _TME_WORDS_BIGENDIAN */
267 };
268 
269 /* 64-bit math: */
270 union tme_value64 *tme_value64_add _TME_P((union tme_value64 *, _tme_const union tme_value64 *));
271 union tme_value64 *tme_value64_sub _TME_P((union tme_value64 *, _tme_const union tme_value64 *));
272 union tme_value64 *tme_value64_mul _TME_P((union tme_value64 *, _tme_const union tme_value64 *));
273 union tme_value64 *tme_value64_div _TME_P((union tme_value64 *, _tme_const union tme_value64 *));
274 union tme_value64 *_tme_value64_set _TME_P((union tme_value64 *, _tme_const tme_uint8_t *, int));
275 #ifdef TME_HAVE_INT64_T
276 #define tme_value64_add(a, b) (((a)->tme_value64_uint += (b)->tme_value64_uint), (a))
277 #define tme_value64_sub(a, b) (((a)->tme_value64_uint -= (b)->tme_value64_uint), (a))
278 #define tme_value64_mul(a, b) (((a)->tme_value64_uint *= (b)->tme_value64_uint), (a))
279 #define tme_value64_div(a, b) (((a)->tme_value64_uint /= (b)->tme_value64_uint), (a))
280 #define tme_value64_imul(a, b) (((a)->tme_value64_int *= (b)->tme_value64_int), (a))
281 #define tme_value64_idiv(a, b) (((a)->tme_value64_int /= (b)->tme_value64_int), (a))
282 #define tme_value64_set(a, b) (((b) >= 0) ? ((a)->tme_value64_uint = (b), (a)) : ((a)->tme_value64_int = (b), (a)))
283 #define tme_value64_cmp(a, cmp, b) ((a)->tme_value64_uint cmp (b)->tme_value64_uint)
284 #else  /* !TME_HAVE_INT64_T */
285 #define tme_value64_set(a, b) _tme_value64_set(a, (_tme_const tme_uint8_t *) &(b), ((b) >= 0 ? sizeof(b) : -sizeof(b)))
286 #define _tme_value64_cmp32(half, a, cmp, b)			\
287   ((a)->tme_value64_uint._TME_CONCAT(tme_value64_uint32_,half)	\
288    cmp (b)->tme_value64_uint._TME_CONCAT(tme_value64_uint32_,half))
289 #define tme_value64_cmp(a, cmp, b)				\
290   (((2 cmp 1)							\
291     ? _tme_value32_cmp32(hi, a, >, b)				\
292     : (1 cmp 2)							\
293     ? _tme_value32_cmp32(hi, a, <, b)				\
294     : FALSE)							\
295    || (_tme_value32_cmp32(hi, a, ==, b)				\
296        && _tme_value32_cmp32(lo, a, cmp, b)))
297 #endif /* !TME_HAVE_INT64_T */
298 
299 /* 64-bit byte swapping: */
300 #ifdef TME_HAVE_INT64_T
301 #ifdef _TME_HAVE_BSWAP64
302 #define tme_bswap_u64(x) ((tme_uint64_t) bswap64((tme_uint64_t) (x)))
303 #else  /* !_TME_HAVE_BSWAP64 */
304 static _tme_inline tme_uint64_t
tme_bswap_u64(tme_uint64_t x)305 tme_bswap_u64(tme_uint64_t x)
306 {
307   return ((((tme_uint64_t) tme_bswap_u32((tme_uint32_t) x)) << 32)
308 	  | tme_bswap_u32((tme_uint32_t) (x >> 32)));
309 }
310 #endif /* !_TME_HAVE_BSWAP64 */
311 #endif /* TME_HAVE_INT64_T */
312 
313 /* versions: */
314 #define TME_X_VERSION(current, age)	(((current) << 10) | (age))
315 #define TME_X_VERSION_CURRENT(version)	((version) >> 10)
316 #define TME_X_VERSION_AGE(version)	((version) & 0x3ff)
317 #define TME_X_VERSION_OK(vimpl, vneed)						\
318   TME_RANGES_OVERLAP(TME_X_VERSION_CURRENT(vneed) - TME_X_VERSION_AGE(vneed),	\
319 		     TME_X_VERSION_CURRENT(vneed),				\
320 		     TME_X_VERSION_CURRENT(vimpl) - TME_X_VERSION_AGE(vimpl),	\
321 		     TME_X_VERSION_CURRENT(vimpl))
322 
323 /* printf formats: */
324 #define _TME_PRI8 ""
325 #define _TME_PRI16 ""
326 #define TME_PRIx8 _TME_PRI8 "x"
327 #define TME_PRIx16 _TME_PRI16 "x"
328 #define TME_PRIx32 _TME_PRI32 "x"
329 #define TME_PRIx64 _TME_PRI64 "x"
330 
331 /* miscellaneous: */
332 #define TME_ARRAY_ELS(x)	(sizeof(x) / sizeof(x[0]))
333 #define TME_EMULATOR_OFF_UNDEF	((void *) (-1))
334 #define TME_RANGES_OVERLAP(low0, high0, low1, high1)	\
335   (((high0) >= (low1)) && ((high1) >= (low0)))
336 #define TME_ARG_IS(s, x)	((s) != NULL && !strcmp(s, x))
337 #define TME_OK			(0)
338 
339 /* prototypes: */
340 void *tme_malloc _TME_P((unsigned int));
341 void *tme_malloc0 _TME_P((unsigned int));
342 void *tme_realloc _TME_P((void *, unsigned int));
343 void *tme_memdup _TME_P((_tme_const void *, unsigned int));
344 void tme_free _TME_P((void *));
345 void tme_free_string_array _TME_P((char **, int));
346 char *tme_strdup _TME_P((_tme_const char *));
347 
348 #ifdef _TME_IMPL
349 /* string and memory prototypes: */
350 #ifdef STDC_HEADERS
351 #include <stdlib.h>
352 #include <string.h>
353 #else  /* !STDC_HEADERS */
354 void *memcpy _TME_P((void *, _tme_const void *, size_t));
355 void *memset _TME_P((void *, int, size_t));
356 void *memmove _TME_P((void *, _tme_const void *, size_t));
357 #endif /* !STDC_HEADERS */
358 #endif /* _TME_IMPL */
359 
360 #endif /* !_TME_COMMON_H */
361