Fixup assert definitions.
[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
58 #ifdef UNUSED
59 #undef UNUSED
60 #define UNUSED(x) SXE_UNUSED(x)
61 #endif
62
63 #ifdef SXE_SET_UNUSED
64 #else
65 #  define SXE_SET_UNUSED(x) ((void)(x))
66 #endif
67
68 #ifdef WEAK_EXTERN
69 #elif defined(__GNUC__)
70 # define WEAK_EXTERN    extern __attribute__((weak))
71 #else
72 # error "Grrr, bloody 'ell, can't figure out how to create weak symbols"
73 #endif
74
75 #ifdef WEAK
76 #elif defined(__GNUC__)
77 # define WEAK           __attribute__((weak))
78 #else
79 # error "Grrr, bloody 'ell, can't figure out how to create weak symbols"
80 #endif
81
82
83 #ifdef LIKELY
84 #else
85 #define LIKELY(_x)      __builtin_expect(!!(_x), 1)
86 #endif
87
88 #ifdef UNLIKELY
89 #else
90 #define UNLIKELY(_x)    __builtin_expect(!!(_x), 0)
91 #endif
92
93 \f
94 #define extern_inline   static inline
95
96 #ifdef ALL_DEBUG_FLAGS
97 #undef SXE_DEBUG_FLAG
98 #define SXE_DEBUG_FLAG
99 #endif
100
101 #define __SXE_DEBUG__(args...)          fprintf(stderr, "SXE " args)
102 #ifndef SXE_DEBUG_FLAG
103 #define SXE_DEBUG(args...)
104 #else
105 #define SXE_DEBUG(args...)              __SXE_DEBUG__(args)
106 #endif
107 #define SXE_DEBUG_PT(args...)           SXE_DEBUG("[pthread]: " args)
108 #define SXE_CRITICAL(args...)           __SXE_DEBUG__("CRITICAL: " args)
109
110
111 /* We define assert iff USE_ASSERTIONS or DEBUG_SXEMACS is defined.
112    Otherwise we define it to be empty.  Quantify has shown that the
113    time the assert checks take is measurable so let's not include them
114    in production binaries. */
115
116 #if defined(USE_ASSERTIONS) && defined(emacs)
117 /* Highly dubious kludge */
118 /*   (thanks, Jamie, I feel better now -- ben) */
119 void assert_failed(const char *, int, const char *);
120 # define abort() (assert_failed (__FILE__, __LINE__, "abort()"))
121 # define assert(x) ((x) ? (void) 0 : assert_failed (__FILE__, __LINE__, #x))
122 #else
123 # ifdef DEBUG_SXEMACS
124 #  define assert(x) ((x) ? (void) 0 : (void) abort ())
125 # else
126 #  define assert(x) ((void)0)
127 # endif
128 #endif
129
130 /* from c.ac */
131 #ifndef BITS_PER_CHAR
132 #define BITS_PER_CHAR 8
133 #endif
134 #define SXE_SHORTBITS (SIZEOF_SHORT * BITS_PER_CHAR)
135 #define SXE_INTBITS (SIZEOF_INT * BITS_PER_CHAR)
136 #define SXE_LONGBITS (SIZEOF_LONG * BITS_PER_CHAR)
137 #define SXE_LONG_LONG_BITS (SIZEOF_LONG_LONG_INT * BITS_PER_CHAR)
138 #define SXE_VOID_P_BITS (SIZEOF_VOID_P * BITS_PER_CHAR)
139
140 /* Also define min() and max(). (Some compilers put them in strange
141    places that won't be referenced by the above include files, such
142    as 'macros.h' under Solaris.) */
143
144 #ifndef min
145 #define min(a,b) (((a) <= (b)) ? (a) : (b))
146 #endif
147 #ifndef max
148 #define max(a,b) (((a) > (b)) ? (a) : (b))
149 #endif
150
151 \f
152 #define countof(x) ((int) (sizeof(x)/sizeof((x)[0])))
153
154 #if !defined HAVE_DECL_STRDUP
155 extern char *strdup(const char *s);
156 #endif  /* HAVE_DECL_STRDUP */
157
158 \f
159 #ifndef PRINTF_ARGS
160 # if defined (__GNUC__) && (__GNUC__ >= 2)
161 #  define PRINTF_ARGS(string_index,first_to_check) \
162           __attribute__ ((format (printf, string_index, first_to_check)))
163 # else
164 #  define PRINTF_ARGS(string_index,first_to_check)
165 # endif                         /* GNUC */
166 #endif
167
168 #ifndef DOESNT_RETURN
169 # if defined __GNUC__
170 #  if ((__GNUC__ > 2) || (__GNUC__ == 2) && (__GNUC_MINOR__ >= 5))
171 #   define DOESNT_RETURN void
172 #   define DECLARE_DOESNT_RETURN(decl) \
173            extern void decl __attribute__ ((noreturn))
174 #   define DECLARE_DOESNT_RETURN_GCC_ATTRIBUTE_SYNTAX_SUCKS(decl,str,idx) \
175      /* Should be able to state multiple independent __attribute__s, but  \
176         the losing syntax doesn't work that way, and screws losing cpp */ \
177            extern void decl \
178                   __attribute__ ((noreturn, format (printf, str, idx)))
179 #  else
180 #   define DOESNT_RETURN void volatile
181 #   define DECLARE_DOESNT_RETURN(decl) extern void volatile decl
182 #   define DECLARE_DOESNT_RETURN_GCC_ATTRIBUTE_SYNTAX_SUCKS(decl,str,idx) \
183            extern void volatile decl PRINTF_ARGS(str,idx)
184 #  endif                        /* GNUC 2.5 */
185 # else
186 #  define DOESNT_RETURN void
187 #  define DECLARE_DOESNT_RETURN(decl) extern void decl
188 #  define DECLARE_DOESNT_RETURN_GCC_ATTRIBUTE_SYNTAX_SUCKS(decl,str,idx) \
189           extern void decl PRINTF_ARGS(str,idx)
190 # endif                         /* GNUC */
191 #endif
192
193 \f
194 /* No type has a greater alignment requirement than max_align_t.
195    (except perhaps for types we don't use, like long double) */
196 typedef union {
197         struct {
198                 long l;
199         } l;
200         struct {
201                 void *p;
202         } p;
203         struct {
204                 void (*f) (void);
205         } f;
206         struct {
207                 double d;
208         } d;
209 } max_align_t;
210
211 #ifndef ALIGNOF
212 # if defined (__GNUC__) && (__GNUC__ >= 2)
213 /* gcc has an extension that gives us exactly what we want. */
214 #  define ALIGNOF(type) __alignof__ (type)
215 # elif ! defined (__cplusplus)
216 /* The following is mostly portable, except that:
217    - it doesn't work for inside out declarations like void (*) (void).
218      (so just call ALIGNOF with a typedef'ed name)
219    - it doesn't work with C++.  The C++ committee has decided,
220      in its infinite wisdom, that:
221      "Types must be declared in declarations, not in expressions." */
222 #  define ALIGNOF(type) offsetof (struct { char c; type member; }, member)
223 # else
224 /* C++ is annoying, but it has a big bag of tricks.
225    The following doesn't have the "inside out" declaration bug C does. */
226 template < typename T > struct alignment_trick {
227         char c;
228         T member;
229 };
230 #  define ALIGNOF(type) offsetof (alignment_trick<type>, member)
231 # endif
232 #endif                          /* ALIGNOF */
233
234 #define ALIGN_SIZE(len, unit) \
235   ((((len) + (unit) - 1) / (unit)) * (unit))
236
237 /* #### Yuck, this is kind of evil */
238 #define ALIGN_PTR(ptr, unit) \
239   ((void *) ALIGN_SIZE ((size_t) (ptr), unit))
240
241 #ifndef DO_NOTHING
242 #define DO_NOTHING do {} while (0)
243 #endif
244
245 #ifndef DECLARE_NOTHING
246 #define DECLARE_NOTHING struct nosuchstruct
247 #endif
248
249 \f
250 /* str funs */
251 #define xstrlen         strlen
252 #define xstrcmp         strcmp
253 #define xstrncmp        strncmp
254 #define xstrncat        strncat
255
256 extern_inline char*
257 xstrncpy(char* target, const char*source, size_t len)
258         __attribute__((always_inline));
259 extern_inline char*
260 xstrncpy(char* target, const char*source, size_t len)
261 {
262         *target ='\0';
263         return strncat(target,source,len-1);
264 }
265
266 #if !defined(FORBID_STRCPY)
267 #  define xstrcat               strcat
268 #  define xstrcpy               strcpy
269 #  if defined(HAVE_STPCPY)
270 #     define xstpcpy    stpcpy
271 #   else
272 extern_inline char*
273 xstpcpy(char *target, const char *source)
274         __attribute__((always_inline));
275 extern_inline char*
276 xstpcpy(char *target, const char *source)
277 {
278         char *p = target;
279         size_t len = xstrlen(source);
280
281         strcpy(target, source);
282         p += len;
283         return p;
284 }
285 #   endif
286 #else
287 #  if defined(strcpy)
288 #    undef strcpy
289 #  endif
290 #  define strcpy  no_strcpy
291 extern_inline char*
292 no_strcpy(char*,const char*)
293         __attribute__((always_inline));
294 extern_inline char*
295 no_strcpy(char * SXE_UNUSED(target),const char * SXE_UNUSED(source))
296 {
297         assert(0);
298         return NULL;
299 }
300 #  if defined(strcat)
301 #    undef strcat
302 #  endif
303 #  define strcat  no_strcat
304 extern_inline char*
305 no_strcat(char*,const char*)
306         __attribute__((always_inline));
307 extern_inline char*
308 no_strcat(char * SXE_UNUSED(target), const char* SXE_UNUSED(source))
309 {
310         assert(0);
311         return NULL;
312 }
313 #  if defined(stpcpy)
314 #    undef stpcpy
315 #  endif
316 #  define stpcpy        no_stpcpy
317 #  define xstpcpy       no_stpcpy
318 extern_inline char*
319 no_stpcpy(char*,const char*)
320         __attribute__((always_inline));
321 extern_inline char*
322 no_stpcpy(char* SXE_UNUSED(target),const char* SXE_UNUSED(source))
323 {
324         assert(0);
325         return NULL;
326 }
327 #endif
328
329
330 #if defined HAVE_STPNCPY
331 # define xstpncpy       stpncpy
332 #else
333 extern_inline char*
334 xstpncpy(char *target, const char *source, size_t len)
335         __attribute__((always_inline));
336 extern_inline char*
337 xstpncpy(char *target, const char *source, size_t len)
338 {
339         char *p = target;
340         xstrncpy(target, source, len);
341         p += len;
342         return p;
343 }
344 #endif  /* !HAVE_STPNCPY */
345
346 #define xmemcmp         memcmp
347 #define xmemcpy         memcpy
348
349
350
351 extern_inline size_t
352 xmin_size_t(size_t a, size_t b)
353         __attribute__((always_inline));
354 extern_inline size_t
355 xmin_size_t(size_t a, size_t b)
356 {
357         if (a < b) {
358                 return a;
359         } else {
360                 return b;
361         }
362 }
363
364 #endif