1 /* Utility definitions for C code of SXEmacs
3 Copyright (C) 1985-1987, 1992-1995 Free Software Foundation, Inc.
4 Copyright (C) 1993-1996 Richard Mlynarik.
5 Copyright (C) 1995, 1996, 2000 Ben Wing.
6 Copyright (C) 2004 Steve Youngs.
7 Copyright (C) 2011 Nelson Ferreira.
9 This file is part of SXEmacs
11 SXEmacs is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 SXEmacs is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>. */
24 /* NOT synched with FSF */
25 #ifndef INCLUDED_sxe_utils_h_
26 #define INCLUDED_sxe_utils_h_
28 /* ------------------------ include files ------------------- */
30 /* We include the following generally useful header files so that you
31 don't have to worry about prototypes when using the standard C
32 library functions and macros. These files shouldn't be excessively
33 large so they shouldn't cause that much of a slowdown. */
36 #include <string.h> /* primarily for memcpy, etc. */
37 #include <stdio.h> /* NULL, etc. */
40 #include <stddef.h> /* offsetof */
41 #include <sys/types.h>
43 #if defined HAVE_STDBOOL_H
50 #elif defined(__GNUC__)
51 # define UNUSED(x) UNUSED_ ## x __attribute__((unused))
52 #elif defined(__LCLINT__)
53 # define UNUSED(x) /*@unused@*/ x
59 #elif defined(__GNUC__)
60 # define WEAK_EXTERN extern __attribute__((weak))
62 # error "Grrr, bloody 'ell, can't figure out how to create weak symbols"
66 #elif defined(__GNUC__)
67 # define WEAK __attribute__((weak))
69 # error "Grrr, bloody 'ell, can't figure out how to create weak symbols"
75 #define LIKELY(_x) __builtin_expect(!!(_x), 1)
79 #define UNLIKELY(_x) __builtin_expect(!!(_x), 0)
84 #if defined SXE_STATIC_EXTERN_INLINE
85 # define extern_inline static inline
86 #elif !defined __GNUC_STDC_INLINE__ && !defined SXE_INLINE_NO_EXTERN
87 # define extern_inline extern inline
89 # define extern_inline inline
92 #ifdef ALL_DEBUG_FLAGS
94 #define SXE_DEBUG_FLAG
97 #define __SXE_DEBUG__(args...) fprintf(stderr, "SXE " args)
98 #ifndef SXE_DEBUG_FLAG
99 #define SXE_DEBUG(args...)
101 #define SXE_DEBUG(args...) __SXE_DEBUG__(args)
103 #define SXE_DEBUG_PT(args...) SXE_DEBUG("[pthread]: " args)
104 #define SXE_CRITICAL(args...) __SXE_DEBUG__("CRITICAL: " args)
108 /* We define assert iff USE_ASSERTIONS or DEBUG_SXEMACS is defined.
109 Otherwise we define it to be empty. Quantify has shown that the
110 time the assert checks take is measurable so let's not include them
111 in production binaries. */
113 #ifdef USE_ASSERTIONS
114 /* Highly dubious kludge */
115 /* (thanks, Jamie, I feel better now -- ben) */
116 void assert_failed(const char *, int, const char *);
117 # define abort() (assert_failed (__FILE__, __LINE__, "abort()"))
118 # define assert(x) ((x) ? (void) 0 : assert_failed (__FILE__, __LINE__, #x))
120 # ifdef DEBUG_SXEMACS
121 # define assert(x) ((x) ? (void) 0 : (void) abort ())
128 #ifndef BITS_PER_CHAR
129 #define BITS_PER_CHAR 8
131 #define SXE_SHORTBITS (SIZEOF_SHORT * BITS_PER_CHAR)
132 #define SXE_INTBITS (SIZEOF_INT * BITS_PER_CHAR)
133 #define SXE_LONGBITS (SIZEOF_LONG * BITS_PER_CHAR)
134 #define SXE_LONG_LONG_BITS (SIZEOF_LONG_LONG_INT * BITS_PER_CHAR)
135 #define SXE_VOID_P_BITS (SIZEOF_VOID_P * BITS_PER_CHAR)
137 /* Also define min() and max(). (Some compilers put them in strange
138 places that won't be referenced by the above include files, such
139 as 'macros.h' under Solaris.) */
142 #define min(a,b) (((a) <= (b)) ? (a) : (b))
145 #define max(a,b) (((a) > (b)) ? (a) : (b))
149 /* generally useful */
150 #define countof(x) ((int) (sizeof(x)/sizeof((x)[0])))
151 #define xnew(type) ((type *) xmalloc (sizeof (type)))
152 #define xnew_atomic(type) ((type *) xmalloc_atomic (sizeof (type)))
153 #define xnew_array(type, len) ((type *) xmalloc ((len) * sizeof (type)))
154 #define xnew_atomic_array(type, len) \
155 ((type*)xmalloc_atomic((len) * sizeof(type)))
156 #define xnew_and_zero(type) ((type *) xmalloc_and_zero (sizeof (type)))
157 #define xzero(lvalue) ((void) memset (&(lvalue), '\0', sizeof (lvalue)))
158 #define xnew_array_and_zero(type, len) \
159 ((type*)xmalloc_and_zero ((len) * sizeof (type)))
160 #define xrealloc_array(ptr, type, len) \
161 ((void) (ptr = (type *) xrealloc (ptr, (len) * sizeof (type))))
162 #define XREALLOC_ARRAY xrealloc_array
163 #define alloca_array(type, len) ((type *) alloca ((len) * sizeof (type)))
165 #if !defined HAVE_DECL_STRDUP
166 extern char *strdup(const char *s);
167 #endif /* HAVE_DECL_STRDUP */
171 # if defined (__GNUC__) && (__GNUC__ >= 2)
172 # define PRINTF_ARGS(string_index,first_to_check) \
173 __attribute__ ((format (printf, string_index, first_to_check)))
175 # define PRINTF_ARGS(string_index,first_to_check)
179 #ifndef DOESNT_RETURN
180 # if defined __GNUC__
181 # if ((__GNUC__ > 2) || (__GNUC__ == 2) && (__GNUC_MINOR__ >= 5))
182 # define DOESNT_RETURN void
183 # define DECLARE_DOESNT_RETURN(decl) \
184 extern void decl __attribute__ ((noreturn))
185 # define DECLARE_DOESNT_RETURN_GCC_ATTRIBUTE_SYNTAX_SUCKS(decl,str,idx) \
186 /* Should be able to state multiple independent __attribute__s, but \
187 the losing syntax doesn't work that way, and screws losing cpp */ \
189 __attribute__ ((noreturn, format (printf, str, idx)))
191 # define DOESNT_RETURN void volatile
192 # define DECLARE_DOESNT_RETURN(decl) extern void volatile decl
193 # define DECLARE_DOESNT_RETURN_GCC_ATTRIBUTE_SYNTAX_SUCKS(decl,str,idx) \
194 extern void volatile decl PRINTF_ARGS(str,idx)
195 # endif /* GNUC 2.5 */
197 # define DOESNT_RETURN void
198 # define DECLARE_DOESNT_RETURN(decl) extern void decl
199 # define DECLARE_DOESNT_RETURN_GCC_ATTRIBUTE_SYNTAX_SUCKS(decl,str,idx) \
200 extern void decl PRINTF_ARGS(str,idx)
205 /* No type has a greater alignment requirement than max_align_t.
206 (except perhaps for types we don't use, like long double) */
223 # if defined (__GNUC__) && (__GNUC__ >= 2)
224 /* gcc has an extension that gives us exactly what we want. */
225 # define ALIGNOF(type) __alignof__ (type)
226 # elif ! defined (__cplusplus)
227 /* The following is mostly portable, except that:
228 - it doesn't work for inside out declarations like void (*) (void).
229 (so just call ALIGNOF with a typedef'ed name)
230 - it doesn't work with C++. The C++ committee has decided,
231 in its infinite wisdom, that:
232 "Types must be declared in declarations, not in expressions." */
233 # define ALIGNOF(type) offsetof (struct { char c; type member; }, member)
235 /* C++ is annoying, but it has a big bag of tricks.
236 The following doesn't have the "inside out" declaration bug C does. */
237 template < typename T > struct alignment_trick {
241 # define ALIGNOF(type) offsetof (alignment_trick<type>, member)
245 #define ALIGN_SIZE(len, unit) \
246 ((((len) + (unit) - 1) / (unit)) * (unit))
248 /* #### Yuck, this is kind of evil */
249 #define ALIGN_PTR(ptr, unit) \
250 ((void *) ALIGN_SIZE ((size_t) (ptr), unit))
253 #define DO_NOTHING do {} while (0)
256 #ifndef DECLARE_NOTHING
257 #define DECLARE_NOTHING struct nosuchstruct
261 /************************************************************************/
263 /************************************************************************/
265 #ifdef ALL_DEBUG_FLAGS
267 #define GC_DEBUG_FLAG
270 #if !defined GC_DEBUG_FLAG
271 # define SXE_DEBUG_GC(args...)
273 # define SXE_DEBUG_GC(args...) __SXE_DEBUG__("[gc] " args)
275 #define SXE_DEBUG_GC_PT(args...) SXE_DEBUG_GC("[pthread]: " args)
276 #define SXE_CRITICAL_GC(args...) __SXE_DEBUG__("[gc] CRITICAL: " args)
278 void malloc_warning(const char *);
280 #if defined HAVE_BDWGC && defined EF_USE_BDWGC
281 # if defined HAVE_THREADS
282 # if !defined GC_PTHREADS
283 # define GC_PTHREADS 1
284 # endif /* !GC_PTHREADS */
285 # if !defined GC_THREADS
286 # define GC_THREADS 1
287 # endif /* !GC_THREADS */
288 # endif /* HAVE_THREADS */
291 # if defined GC_DEBUG_FLAG
293 # endif /* GC_DEBUG_FLAG */
294 # if defined HAVE_GC_GC_H
296 # elif defined HAVE_GC_H
299 # error "Take less of those pills!"
302 # if defined GC_DEBUG_FLAG
303 # define zmalloc GC_MALLOC_IGNORE_OFF_PAGE
304 # define zcalloc(n, m) GC_MALLOC((n)*(m))
305 # define zmalloc_atomic GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE
306 # define zmalloc_and_zero GC_MALLOC
307 # define zrealloc GC_REALLOC
308 # define zstrdup GC_STRDUP
310 # define zfree(x) GC_FREE(x)
311 # else /* !GC_DEBUG_FLAG */
312 # define zmalloc GC_malloc_ignore_off_page
313 # define zcalloc(n, m) GC_malloc((n)*(m))
314 # define zmalloc_atomic GC_malloc_atomic_ignore_off_page
315 # define zmalloc_and_zero GC_malloc
316 # define zrealloc GC_realloc
317 # define zstrdup GC_strdup
320 # endif /* GC_DEBUG_FLAG */
325 #define zmalloc_atomic F&^!
326 #define zmalloc_and_zero F&^!
327 #define zrealloc F&^!
328 #define zstrdrup F&^!
331 /* also define libc mem funs */
332 #define ymalloc malloc
333 #define ycalloc(n, m) calloc(n, m)
334 #define ymalloc_atomic(n) ycalloc(1, n)
335 #define ymalloc_and_zero(x) ycalloc(1, x)
336 #define yrealloc realloc
337 #define ystrdup strdup
338 #define yfree(x) free(x)
339 /* and their convenience companions */
340 #define ynew(type) ((type*)ymalloc(sizeof(type)))
341 #define ynew_array(type, len) ((type*)ymalloc((len) * sizeof(type)))
342 #define ynew_and_zero(type) ((type*)ymalloc_and_zero(sizeof(type)))
343 #define ynew_array_and_zero(type, len) \
344 ((type*)ymalloc_and_zero((len) * sizeof(type)))
345 #define YREALLOC_ARRAY(ptr, type, len) \
346 ((void)(ptr = (type *)yrealloc(ptr, (len) * sizeof (type))))
348 #if defined HAVE_BDWGC && defined EF_USE_BDWGC
349 /* and now the x* series */
350 # define xmalloc zmalloc
351 # define xcalloc zcalloc
352 # define xmalloc_atomic zmalloc_atomic
353 # define xmalloc_and_zero zmalloc_and_zero
354 # define xrealloc zrealloc
355 # define xstrdup zstrdup
356 # if defined ERROR_CHECK_MALLOC
357 # define xfree(args...) zfree(args)
358 # else /* !ERROR_CHECK_MALLOC */
359 # define xfree(args...)
360 # endif /* ERROR_CHECK_MALLOC */
363 void *xmalloc(size_t size);
364 void *xmalloc_atomic(size_t size);
365 void *xmalloc_and_zero(size_t size);
366 void *xrealloc(void *, size_t size);
367 char *xstrdup(const char *);
368 # if defined ERROR_CHECK_MALLOC
369 # if SIZEOF_VOID_P == 4
370 # define xfree(lvalue) \
372 void *volatile *xfree_ptr = \
374 ((volatile void*)&(lvalue)); \
375 assert(*xfree_ptr != (void*)0xB00BB4BE); \
377 *xfree_ptr = (void*)0xB00BB4BE; \
379 # elif SIZEOF_VOID_P == 8
380 # define xfree(lvalue) \
382 void *volatile *xfree_ptr = \
384 ((volatile void*)&(lvalue)); \
385 assert(*xfree_ptr != (void*)0xCAFEBABEDEADBEEF); \
387 *xfree_ptr = (void*)0xCAFEBABEDEADBEEF; \
390 # error "Strange-arse system detected. Watch a movie, it\'s more fun!"
392 # else /* !ERROR_CHECK_MALLOC */
393 # define xfree(args...) yfree(args)
394 # endif /* ERROR_CHECK_MALLOC */