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