from Sebastian
[sxemacs] / src / sxe-utils.h
1 /* Utility definitions for C code of SXEmacs 
2
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.
8
9 This file is part of SXEmacs
10
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.
15
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.
20
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/>. */
23
24 /* NOT synched with FSF */
25 #ifndef INCLUDED_sxe_utils_h_
26 #define INCLUDED_sxe_utils_h_
27
28 /* ------------------------ include files ------------------- */
29
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. */
34
35 #include <stdlib.h>
36 #include <string.h>             /* primarily for memcpy, etc. */
37 #include <stdio.h>              /* NULL, etc. */
38 #include <ctype.h>
39 #include <stdarg.h>
40 #include <stddef.h>             /* offsetof */
41 #include <sys/types.h>
42 #include <limits.h>
43 #if defined HAVE_STDBOOL_H
44 # include <stdbool.h>
45 #endif
46
47 \f
48 /* goodies */
49 #ifdef SXE_UNUSED
50 #elif defined(__GNUC__)
51 # define SXE_UNUSED(x) UNUSED_ ## x __attribute__((unused))
52 #elif defined(__LCLINT__)
53 # define SXE_UNUSED(x) /*@unused@*/ x
54 #else
55 # define SXE_UNUSED(x) x
56 #endif
57 #ifdef UNUSED
58 #undef UNUSED
59 #define UNUSED(x) SXE_UNUSED(x)
60 #endif
61
62 #ifdef WEAK_EXTERN
63 #elif defined(__GNUC__)
64 # define WEAK_EXTERN    extern __attribute__((weak))
65 #else
66 # error "Grrr, bloody 'ell, can't figure out how to create weak symbols"
67 #endif
68
69 #ifdef WEAK
70 #elif defined(__GNUC__)
71 # define WEAK           __attribute__((weak))
72 #else
73 # error "Grrr, bloody 'ell, can't figure out how to create weak symbols"
74 #endif
75
76
77 #ifdef LIKELY
78 #else
79 #define LIKELY(_x)      __builtin_expect(!!(_x), 1)
80 #endif
81 #ifdef UNLIKELY
82 #else
83 #define UNLIKELY(_x)    __builtin_expect(!!(_x), 0)
84 #endif
85
86 \f
87 #define extern_inline   static inline
88
89 #ifdef ALL_DEBUG_FLAGS
90 #undef SXE_DEBUG_FLAG
91 #define SXE_DEBUG_FLAG
92 #endif
93
94 #define __SXE_DEBUG__(args...)          fprintf(stderr, "SXE " args)
95 #ifndef SXE_DEBUG_FLAG
96 #define SXE_DEBUG(args...)
97 #else
98 #define SXE_DEBUG(args...)              __SXE_DEBUG__(args)
99 #endif
100 #define SXE_DEBUG_PT(args...)           SXE_DEBUG("[pthread]: " args)
101 #define SXE_CRITICAL(args...)           __SXE_DEBUG__("CRITICAL: " args)
102
103
104
105 /* We define assert iff USE_ASSERTIONS or DEBUG_SXEMACS is defined.
106    Otherwise we define it to be empty.  Quantify has shown that the
107    time the assert checks take is measurable so let's not include them
108    in production binaries. */
109
110 #ifdef USE_ASSERTIONS
111 /* Highly dubious kludge */
112 /*   (thanks, Jamie, I feel better now -- ben) */
113 void assert_failed(const char *, int, const char *);
114 # define abort() (assert_failed (__FILE__, __LINE__, "abort()"))
115 # define assert(x) ((x) ? (void) 0 : assert_failed (__FILE__, __LINE__, #x))
116 #else
117 # ifdef DEBUG_SXEMACS
118 #  define assert(x) ((x) ? (void) 0 : (void) abort ())
119 # else
120 #  define assert(x)
121 # endif
122 #endif
123
124 /* from c.ac */
125 #ifndef BITS_PER_CHAR
126 #define BITS_PER_CHAR 8
127 #endif
128 #define SXE_SHORTBITS (SIZEOF_SHORT * BITS_PER_CHAR)
129 #define SXE_INTBITS (SIZEOF_INT * BITS_PER_CHAR)
130 #define SXE_LONGBITS (SIZEOF_LONG * BITS_PER_CHAR)
131 #define SXE_LONG_LONG_BITS (SIZEOF_LONG_LONG_INT * BITS_PER_CHAR)
132 #define SXE_VOID_P_BITS (SIZEOF_VOID_P * BITS_PER_CHAR)
133
134 /* Also define min() and max(). (Some compilers put them in strange
135    places that won't be referenced by the above include files, such
136    as 'macros.h' under Solaris.) */
137
138 #ifndef min
139 #define min(a,b) (((a) <= (b)) ? (a) : (b))
140 #endif
141 #ifndef max
142 #define max(a,b) (((a) > (b)) ? (a) : (b))
143 #endif
144
145 \f
146 /* generally useful */
147 #define countof(x) ((int) (sizeof(x)/sizeof((x)[0])))
148 #define xnew(type) ((type *) xmalloc (sizeof (type)))
149 #define xnew_atomic(type) ((type *) xmalloc_atomic (sizeof (type)))
150 #define xnew_array(type, len) ((type *) xmalloc ((len) * sizeof (type)))
151 #define xnew_atomic_array(type, len)                    \
152         ((type*)xmalloc_atomic((len) * sizeof(type)))
153 #define xnew_and_zero(type) ((type *) xmalloc_and_zero (sizeof (type)))
154 #define xzero(lvalue) ((void) memset (&(lvalue), '\0', sizeof (lvalue)))
155 #define xnew_array_and_zero(type, len)                          \
156         ((type*)xmalloc_and_zero ((len) * sizeof (type)))
157 #define xrealloc_array(ptr, type, len)                          \
158         ((void) (ptr = (type *) xrealloc (ptr, (len) * sizeof (type))))
159 #define XREALLOC_ARRAY          xrealloc_array
160 #define alloca_array(type, len) ((type *) alloca ((len) * sizeof (type)))
161
162 #if !defined HAVE_DECL_STRDUP
163 extern char *strdup(const char *s);
164 #endif  /* HAVE_DECL_STRDUP */
165
166 \f
167 #ifndef PRINTF_ARGS
168 # if defined (__GNUC__) && (__GNUC__ >= 2)
169 #  define PRINTF_ARGS(string_index,first_to_check) \
170           __attribute__ ((format (printf, string_index, first_to_check)))
171 # else
172 #  define PRINTF_ARGS(string_index,first_to_check)
173 # endif                         /* GNUC */
174 #endif
175
176 #ifndef DOESNT_RETURN
177 # if defined __GNUC__
178 #  if ((__GNUC__ > 2) || (__GNUC__ == 2) && (__GNUC_MINOR__ >= 5))
179 #   define DOESNT_RETURN void
180 #   define DECLARE_DOESNT_RETURN(decl) \
181            extern void decl __attribute__ ((noreturn))
182 #   define DECLARE_DOESNT_RETURN_GCC_ATTRIBUTE_SYNTAX_SUCKS(decl,str,idx) \
183      /* Should be able to state multiple independent __attribute__s, but  \
184         the losing syntax doesn't work that way, and screws losing cpp */ \
185            extern void decl \
186                   __attribute__ ((noreturn, format (printf, str, idx)))
187 #  else
188 #   define DOESNT_RETURN void volatile
189 #   define DECLARE_DOESNT_RETURN(decl) extern void volatile decl
190 #   define DECLARE_DOESNT_RETURN_GCC_ATTRIBUTE_SYNTAX_SUCKS(decl,str,idx) \
191            extern void volatile decl PRINTF_ARGS(str,idx)
192 #  endif                        /* GNUC 2.5 */
193 # else
194 #  define DOESNT_RETURN void
195 #  define DECLARE_DOESNT_RETURN(decl) extern void decl
196 #  define DECLARE_DOESNT_RETURN_GCC_ATTRIBUTE_SYNTAX_SUCKS(decl,str,idx) \
197           extern void decl PRINTF_ARGS(str,idx)
198 # endif                         /* GNUC */
199 #endif
200
201 \f
202 /* No type has a greater alignment requirement than max_align_t.
203    (except perhaps for types we don't use, like long double) */
204 typedef union {
205         struct {
206                 long l;
207         } l;
208         struct {
209                 void *p;
210         } p;
211         struct {
212                 void (*f) (void);
213         } f;
214         struct {
215                 double d;
216         } d;
217 } max_align_t;
218
219 #ifndef ALIGNOF
220 # if defined (__GNUC__) && (__GNUC__ >= 2)
221 /* gcc has an extension that gives us exactly what we want. */
222 #  define ALIGNOF(type) __alignof__ (type)
223 # elif ! defined (__cplusplus)
224 /* The following is mostly portable, except that:
225    - it doesn't work for inside out declarations like void (*) (void).
226      (so just call ALIGNOF with a typedef'ed name)
227    - it doesn't work with C++.  The C++ committee has decided,
228      in its infinite wisdom, that:
229      "Types must be declared in declarations, not in expressions." */
230 #  define ALIGNOF(type) offsetof (struct { char c; type member; }, member)
231 # else
232 /* C++ is annoying, but it has a big bag of tricks.
233    The following doesn't have the "inside out" declaration bug C does. */
234 template < typename T > struct alignment_trick {
235         char c;
236         T member;
237 };
238 #  define ALIGNOF(type) offsetof (alignment_trick<type>, member)
239 # endif
240 #endif                          /* ALIGNOF */
241
242 #define ALIGN_SIZE(len, unit) \
243   ((((len) + (unit) - 1) / (unit)) * (unit))
244
245 /* #### Yuck, this is kind of evil */
246 #define ALIGN_PTR(ptr, unit) \
247   ((void *) ALIGN_SIZE ((size_t) (ptr), unit))
248
249 #ifndef DO_NOTHING
250 #define DO_NOTHING do {} while (0)
251 #endif
252
253 #ifndef DECLARE_NOTHING
254 #define DECLARE_NOTHING struct nosuchstruct
255 #endif
256
257 \f
258 /************************************************************************/
259 /*                                Memory                                */
260 /************************************************************************/
261
262 #ifdef ALL_DEBUG_FLAGS
263 #undef GC_DEBUG_FLAG
264 #define GC_DEBUG_FLAG
265 #endif
266
267 #if !defined GC_DEBUG_FLAG
268 # define SXE_DEBUG_GC(args...)
269 #else
270 # define SXE_DEBUG_GC(args...)          __SXE_DEBUG__("[gc] " args)
271 #endif
272 #define SXE_DEBUG_GC_PT(args...)        SXE_DEBUG_GC("[pthread]: " args)
273 #define SXE_CRITICAL_GC(args...)        __SXE_DEBUG__("[gc] CRITICAL: " args)
274
275 void malloc_warning(const char *);
276
277 #if defined HAVE_BDWGC && defined EF_USE_BDWGC
278 # if defined HAVE_THREADS
279 #  if !defined GC_PTHREADS
280 #   define GC_PTHREADS  1
281 #  endif  /* !GC_PTHREADS */
282 #  if !defined GC_THREADS
283 #   define GC_THREADS   1
284 #  endif  /* !GC_THREADS */
285 # endif  /* HAVE_THREADS */
286
287 # undef GC_DEBUG
288 # if defined GC_DEBUG_FLAG
289 #  define GC_DEBUG      1
290 # endif  /* GC_DEBUG_FLAG */
291 # if defined HAVE_GC_GC_H
292 #  include <gc/gc.h>
293 # elif defined HAVE_GC_H
294 #  include <gc.h>
295 # else
296 #  error "Take less of those pills!"
297 # endif
298
299 # if defined GC_DEBUG_FLAG
300 #  define zmalloc               GC_MALLOC_IGNORE_OFF_PAGE
301 #  define zcalloc(n, m) GC_MALLOC((n)*(m))
302 #  define zmalloc_atomic        GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE
303 #  define zmalloc_and_zero      GC_MALLOC
304 #  define zrealloc              GC_REALLOC
305 #  define zstrdup               GC_STRDUP
306 #  undef zfree
307 #  define zfree(x)              GC_FREE(x)
308 # else  /* !GC_DEBUG_FLAG */
309 #  define zmalloc               GC_malloc_ignore_off_page
310 #  define zcalloc(n, m)         GC_malloc((n)*(m))
311 #  define zmalloc_atomic        GC_malloc_atomic_ignore_off_page
312 #  define zmalloc_and_zero      GC_malloc
313 #  define zrealloc              GC_realloc
314 #  define zstrdup               GC_strdup
315 #  undef zfree
316 #  define zfree(x)
317 # endif /* GC_DEBUG_FLAG */
318
319 #else  /* !BDWGC */
320 #define zmalloc         F&^!
321 #define zcalloc         F&^!
322 #define zmalloc_atomic  F&^!
323 #define zmalloc_and_zero        F&^!
324 #define zrealloc        F&^!
325 #define zstrdrup        F&^!
326 #endif  /* BDWGC */
327
328 /* also define libc mem funs */
329 #define ymalloc         malloc
330 #define ycalloc(n, m)   calloc(n, m)
331 #define ymalloc_atomic(n)       ycalloc(1, n)
332 #define ymalloc_and_zero(x)     ycalloc(1, x)
333 #define yrealloc        realloc
334 #define ystrdup         strdup
335 #define yfree(x)        free(x)
336 /* and their convenience companions */
337 #define ynew(type)              ((type*)ymalloc(sizeof(type)))
338 #define ynew_array(type, len)   ((type*)ymalloc((len) * sizeof(type)))
339 #define ynew_and_zero(type)     ((type*)ymalloc_and_zero(sizeof(type)))
340 #define ynew_array_and_zero(type, len)                  \
341         ((type*)ymalloc_and_zero((len) * sizeof(type)))
342 #define YREALLOC_ARRAY(ptr, type, len)                                  \
343         ((void)(ptr = (type *)yrealloc(ptr, (len) * sizeof (type))))
344
345 #if defined HAVE_BDWGC && defined EF_USE_BDWGC
346 /* and now the x* series */
347 # define xmalloc                zmalloc
348 # define xcalloc                zcalloc
349 # define xmalloc_atomic         zmalloc_atomic
350 # define xmalloc_and_zero       zmalloc_and_zero
351 # define xrealloc               zrealloc
352 # define xstrdup                zstrdup
353 # if defined ERROR_CHECK_MALLOC
354 #  define xfree(args...)        zfree(args)
355 # else  /* !ERROR_CHECK_MALLOC */
356 #  define xfree(args...)
357 # endif  /* ERROR_CHECK_MALLOC */
358
359 #else  /* !BDWGC */
360 void *xmalloc(size_t size);
361 void *xmalloc_atomic(size_t size);
362 void *xmalloc_and_zero(size_t size);
363 void *xrealloc(void *, size_t size);
364 char *xstrdup(const char *);
365 # if defined ERROR_CHECK_MALLOC
366 #  if SIZEOF_VOID_P == 4
367 #   define xfree(lvalue)                                        \
368         do {                                                    \
369                 void *volatile *xfree_ptr =                     \
370                         (void *volatile*)                       \
371                         ((volatile void*)&(lvalue));            \
372                 assert(*xfree_ptr != (void*)0xB00BB4BE);        \
373                 yfree(*xfree_ptr);                              \
374                 *xfree_ptr = (void*)0xB00BB4BE;                 \
375         } while (0)
376 #  elif SIZEOF_VOID_P == 8
377 #   define xfree(lvalue)                                                        \
378         do {                                                            \
379                 void *volatile *xfree_ptr =                             \
380                         (void *volatile*)                               \
381                         ((volatile void*)&(lvalue));                    \
382                 assert(*xfree_ptr != (void*)0xCAFEBABEDEADBEEF);        \
383                 yfree(*xfree_ptr);                                      \
384                 *xfree_ptr = (void*)0xCAFEBABEDEADBEEF;                 \
385         } while (0)
386 #  else  /* huh? */
387 #   error "Strange-arse system detected.  Watch a movie, it\'s more fun!"
388 #  endif
389 # else  /* !ERROR_CHECK_MALLOC */
390 #  define xfree(args...)        yfree(args)
391 # endif  /* ERROR_CHECK_MALLOC */
392 #endif  /* BDWGC */
393
394 #endif