Coverity fixes from Nelson
[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 UNUSED
50 #elif defined(__GNUC__)
51 # define UNUSED(x) UNUSED_ ## x __attribute__((unused))
52 #elif defined(__LCLINT__)
53 # define UNUSED(x) /*@unused@*/ x
54 #else
55 # define UNUSED(x) x
56 #endif
57
58 #ifdef WEAK_EXTERN
59 #elif defined(__GNUC__)
60 # define WEAK_EXTERN    extern __attribute__((weak))
61 #else
62 # error "Grrr, bloody 'ell, can't figure out how to create weak symbols"
63 #endif
64
65 #ifdef WEAK
66 #elif defined(__GNUC__)
67 # define WEAK           __attribute__((weak))
68 #else
69 # error "Grrr, bloody 'ell, can't figure out how to create weak symbols"
70 #endif
71
72
73 #ifdef LIKELY
74 #else
75 #define LIKELY(_x)      __builtin_expect(!!(_x), 1)
76 #endif
77 #ifdef UNLIKELY
78 #else
79 #define UNLIKELY(_x)    __builtin_expect(!!(_x), 0)
80 #endif
81
82 \f
83
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
88 #else
89 # define extern_inline  inline
90 #endif
91
92 #ifdef ALL_DEBUG_FLAGS
93 #undef SXE_DEBUG_FLAG
94 #define SXE_DEBUG_FLAG
95 #endif
96
97 #define __SXE_DEBUG__(args...)          fprintf(stderr, "SXE " args)
98 #ifndef SXE_DEBUG_FLAG
99 #define SXE_DEBUG(args...)
100 #else
101 #define SXE_DEBUG(args...)              __SXE_DEBUG__(args)
102 #endif
103 #define SXE_DEBUG_PT(args...)           SXE_DEBUG("[pthread]: " args)
104 #define SXE_CRITICAL(args...)           __SXE_DEBUG__("CRITICAL: " args)
105
106
107
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. */
112
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))
119 #else
120 # ifdef DEBUG_SXEMACS
121 #  define assert(x) ((x) ? (void) 0 : (void) abort ())
122 # else
123 #  define assert(x)
124 # endif
125 #endif
126
127 /* from c.ac */
128 #ifndef BITS_PER_CHAR
129 #define BITS_PER_CHAR 8
130 #endif
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)
136
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.) */
140
141 #ifndef min
142 #define min(a,b) (((a) <= (b)) ? (a) : (b))
143 #endif
144 #ifndef max
145 #define max(a,b) (((a) > (b)) ? (a) : (b))
146 #endif
147
148 \f
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)))
164
165 #if !defined HAVE_DECL_STRDUP
166 extern char *strdup(const char *s);
167 #endif  /* HAVE_DECL_STRDUP */
168
169 \f
170 #ifndef PRINTF_ARGS
171 # if defined (__GNUC__) && (__GNUC__ >= 2)
172 #  define PRINTF_ARGS(string_index,first_to_check) \
173           __attribute__ ((format (printf, string_index, first_to_check)))
174 # else
175 #  define PRINTF_ARGS(string_index,first_to_check)
176 # endif                         /* GNUC */
177 #endif
178
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 */ \
188            extern void decl \
189                   __attribute__ ((noreturn, format (printf, str, idx)))
190 #  else
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 */
196 # else
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)
201 # endif                         /* GNUC */
202 #endif
203
204 \f
205 /* No type has a greater alignment requirement than max_align_t.
206    (except perhaps for types we don't use, like long double) */
207 typedef union {
208         struct {
209                 long l;
210         } l;
211         struct {
212                 void *p;
213         } p;
214         struct {
215                 void (*f) (void);
216         } f;
217         struct {
218                 double d;
219         } d;
220 } max_align_t;
221
222 #ifndef ALIGNOF
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)
234 # else
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 {
238         char c;
239         T member;
240 };
241 #  define ALIGNOF(type) offsetof (alignment_trick<type>, member)
242 # endif
243 #endif                          /* ALIGNOF */
244
245 #define ALIGN_SIZE(len, unit) \
246   ((((len) + (unit) - 1) / (unit)) * (unit))
247
248 /* #### Yuck, this is kind of evil */
249 #define ALIGN_PTR(ptr, unit) \
250   ((void *) ALIGN_SIZE ((size_t) (ptr), unit))
251
252 #ifndef DO_NOTHING
253 #define DO_NOTHING do {} while (0)
254 #endif
255
256 #ifndef DECLARE_NOTHING
257 #define DECLARE_NOTHING struct nosuchstruct
258 #endif
259
260 \f
261 /************************************************************************/
262 /*                                Memory                                */
263 /************************************************************************/
264
265 #ifdef ALL_DEBUG_FLAGS
266 #undef GC_DEBUG_FLAG
267 #define GC_DEBUG_FLAG
268 #endif
269
270 #if !defined GC_DEBUG_FLAG
271 # define SXE_DEBUG_GC(args...)
272 #else
273 # define SXE_DEBUG_GC(args...)          __SXE_DEBUG__("[gc] " args)
274 #endif
275 #define SXE_DEBUG_GC_PT(args...)        SXE_DEBUG_GC("[pthread]: " args)
276 #define SXE_CRITICAL_GC(args...)        __SXE_DEBUG__("[gc] CRITICAL: " args)
277
278 void malloc_warning(const char *);
279
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 */
289
290 # undef GC_DEBUG
291 # if defined GC_DEBUG_FLAG
292 #  define GC_DEBUG      1
293 # endif  /* GC_DEBUG_FLAG */
294 # if defined HAVE_GC_GC_H
295 #  include <gc/gc.h>
296 # elif defined HAVE_GC_H
297 #  include <gc.h>
298 # else
299 #  error "Take less of those pills!"
300 # endif
301
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
309 #  undef zfree
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
318 #  undef zfree
319 #  define zfree(x)
320 # endif /* GC_DEBUG_FLAG */
321
322 #else  /* !BDWGC */
323 #define zmalloc         F&^!
324 #define zcalloc         F&^!
325 #define zmalloc_atomic  F&^!
326 #define zmalloc_and_zero        F&^!
327 #define zrealloc        F&^!
328 #define zstrdrup        F&^!
329 #endif  /* BDWGC */
330
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))))
347
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 */
361
362 #else  /* !BDWGC */
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)                                        \
371         do {                                                    \
372                 void *volatile *xfree_ptr =                     \
373                         (void *volatile*)                       \
374                         ((volatile void*)&(lvalue));            \
375                 assert(*xfree_ptr != (void*)0xB00BB4BE);        \
376                 yfree(*xfree_ptr);                              \
377                 *xfree_ptr = (void*)0xB00BB4BE;                 \
378         } while (0)
379 #  elif SIZEOF_VOID_P == 8
380 #   define xfree(lvalue)                                                        \
381         do {                                                            \
382                 void *volatile *xfree_ptr =                             \
383                         (void *volatile*)                               \
384                         ((volatile void*)&(lvalue));                    \
385                 assert(*xfree_ptr != (void*)0xCAFEBABEDEADBEEF);        \
386                 yfree(*xfree_ptr);                                      \
387                 *xfree_ptr = (void*)0xCAFEBABEDEADBEEF;                 \
388         } while (0)
389 #  else  /* huh? */
390 #   error "Strange-arse system detected.  Watch a movie, it\'s more fun!"
391 #  endif
392 # else  /* !ERROR_CHECK_MALLOC */
393 #  define xfree(args...)        yfree(args)
394 # endif  /* ERROR_CHECK_MALLOC */
395 #endif  /* BDWGC */
396
397 #endif