Cleanup utilities. Introduce sxe-memory.h
[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 #define countof(x) ((int) (sizeof(x)/sizeof((x)[0])))
147
148 #if !defined HAVE_DECL_STRDUP
149 extern char *strdup(const char *s);
150 #endif  /* HAVE_DECL_STRDUP */
151
152 \f
153 #ifndef PRINTF_ARGS
154 # if defined (__GNUC__) && (__GNUC__ >= 2)
155 #  define PRINTF_ARGS(string_index,first_to_check) \
156           __attribute__ ((format (printf, string_index, first_to_check)))
157 # else
158 #  define PRINTF_ARGS(string_index,first_to_check)
159 # endif                         /* GNUC */
160 #endif
161
162 #ifndef DOESNT_RETURN
163 # if defined __GNUC__
164 #  if ((__GNUC__ > 2) || (__GNUC__ == 2) && (__GNUC_MINOR__ >= 5))
165 #   define DOESNT_RETURN void
166 #   define DECLARE_DOESNT_RETURN(decl) \
167            extern void decl __attribute__ ((noreturn))
168 #   define DECLARE_DOESNT_RETURN_GCC_ATTRIBUTE_SYNTAX_SUCKS(decl,str,idx) \
169      /* Should be able to state multiple independent __attribute__s, but  \
170         the losing syntax doesn't work that way, and screws losing cpp */ \
171            extern void decl \
172                   __attribute__ ((noreturn, format (printf, str, idx)))
173 #  else
174 #   define DOESNT_RETURN void volatile
175 #   define DECLARE_DOESNT_RETURN(decl) extern void volatile decl
176 #   define DECLARE_DOESNT_RETURN_GCC_ATTRIBUTE_SYNTAX_SUCKS(decl,str,idx) \
177            extern void volatile decl PRINTF_ARGS(str,idx)
178 #  endif                        /* GNUC 2.5 */
179 # else
180 #  define DOESNT_RETURN void
181 #  define DECLARE_DOESNT_RETURN(decl) extern void decl
182 #  define DECLARE_DOESNT_RETURN_GCC_ATTRIBUTE_SYNTAX_SUCKS(decl,str,idx) \
183           extern void decl PRINTF_ARGS(str,idx)
184 # endif                         /* GNUC */
185 #endif
186
187 \f
188 /* No type has a greater alignment requirement than max_align_t.
189    (except perhaps for types we don't use, like long double) */
190 typedef union {
191         struct {
192                 long l;
193         } l;
194         struct {
195                 void *p;
196         } p;
197         struct {
198                 void (*f) (void);
199         } f;
200         struct {
201                 double d;
202         } d;
203 } max_align_t;
204
205 #ifndef ALIGNOF
206 # if defined (__GNUC__) && (__GNUC__ >= 2)
207 /* gcc has an extension that gives us exactly what we want. */
208 #  define ALIGNOF(type) __alignof__ (type)
209 # elif ! defined (__cplusplus)
210 /* The following is mostly portable, except that:
211    - it doesn't work for inside out declarations like void (*) (void).
212      (so just call ALIGNOF with a typedef'ed name)
213    - it doesn't work with C++.  The C++ committee has decided,
214      in its infinite wisdom, that:
215      "Types must be declared in declarations, not in expressions." */
216 #  define ALIGNOF(type) offsetof (struct { char c; type member; }, member)
217 # else
218 /* C++ is annoying, but it has a big bag of tricks.
219    The following doesn't have the "inside out" declaration bug C does. */
220 template < typename T > struct alignment_trick {
221         char c;
222         T member;
223 };
224 #  define ALIGNOF(type) offsetof (alignment_trick<type>, member)
225 # endif
226 #endif                          /* ALIGNOF */
227
228 #define ALIGN_SIZE(len, unit) \
229   ((((len) + (unit) - 1) / (unit)) * (unit))
230
231 /* #### Yuck, this is kind of evil */
232 #define ALIGN_PTR(ptr, unit) \
233   ((void *) ALIGN_SIZE ((size_t) (ptr), unit))
234
235 #ifndef DO_NOTHING
236 #define DO_NOTHING do {} while (0)
237 #endif
238
239 #ifndef DECLARE_NOTHING
240 #define DECLARE_NOTHING struct nosuchstruct
241 #endif
242
243 \f
244 /* str funs */
245 #define xstrlen         strlen
246 #define xstrcmp         strcmp
247 #define xstrncmp        strncmp
248 #define xstrncat        strncat
249
250 extern_inline char*
251 xstrncpy(char* target, const char*source, size_t len)
252         __attribute__((always_inline));
253 extern_inline char*
254 xstrncpy(char* target, const char*source, size_t len)
255 {
256         *target ='\0';
257         return strncat(target,source,len-1);
258 }
259
260 #if !defined(FORBID_STRCPY)
261 #  define xstrcat               strcat
262 #  define xstrcpy               strcpy
263 #  if defined(HAVE_STPCPY)
264 #     define xstpcpy    stpcpy
265 #   else
266 extern_inline char*
267 xstpcpy(char *target, const char *source)
268         __attribute__((always_inline));
269 extern_inline char*
270 xstpcpy(char *target, const char *source)
271 {
272         char *p = target;
273         size_t len = xstrlen(source);
274
275         strcpy(target, source);
276         p += len;
277         return p;
278 }
279 #   endif
280 #else
281 #  if defined(strcpy)
282 #    undef strcpy
283 #  endif
284 #  define strcpy  no_strcpy
285 extern_inline char*
286 no_strcpy(char*,const char*)
287         __attribute__((always_inline));
288 extern_inline char*
289 no_strcpy(char * SXE_UNUSED(target),const char * SXE_UNUSED(source))
290 {
291         assert(0);
292         return NULL;
293 }
294 #  if defined(strcat)
295 #    undef strcat
296 #  endif
297 #  define strcat  no_strcat
298 extern_inline char*
299 no_strcat(char*,const char*)
300         __attribute__((always_inline));
301 extern_inline char*
302 no_strcat(char * SXE_UNUSED(target), const char* SXE_UNUSED(source))
303 {
304         assert(0);
305         return NULL;
306 }
307 #  if defined(stpcpy)
308 #    undef stpcpy
309 #  endif
310 #  define stpcpy        no_stpcpy
311 #  define xstpcpy       no_stpcpy
312 extern_inline char*
313 no_stpcpy(char*,const char*)
314         __attribute__((always_inline));
315 extern_inline char*
316 no_stpcpy(char* SXE_UNUSED(target),const char* SXE_UNUSED(source))
317 {
318         assert(0);
319         return NULL;
320 }
321 #endif
322
323
324 #if defined HAVE_STPNCPY
325 # define xstpncpy       stpncpy
326 #else
327 extern_inline char*
328 xstpncpy(char *target, const char *source, size_t len)
329         __attribute__((always_inline));
330 extern_inline char*
331 xstpncpy(char *target, const char *source, size_t len)
332 {
333         char *p = target;
334         xstrncpy(target, source, len);
335         p += len;
336         return p;
337 }
338 #endif  /* !HAVE_STPNCPY */
339
340 #define xmemcmp         memcmp
341 #define xmemcpy         memcpy
342
343
344
345 extern_inline size_t
346 xmin_size_t(size_t a, size_t b)
347         __attribute__((always_inline));
348 extern_inline size_t
349 xmin_size_t(size_t a, size_t b)
350 {
351         if (a < b) {
352                 return a;
353         } else {
354                 return b;
355         }
356 }
357
358 #endif