1 /*
2 # This file is part of the Astrometry.net suite.
3 # Licensed under a 3-clause BSD style license - see LICENSE
4 */
5 #ifndef OS_FEATURES_H
6 #define OS_FEATURES_H
7 
8 #include "astrometry/os-features-config.h"
9 
10 // Features we use that aren't standard across all supported platforms
11 
12 // Not POSIX; doesn't exist in Solaris 10
13 #include <sys/param.h>
14 #ifndef MIN
15 #define	MIN(a,b) (((a)<(b))?(a):(b))
16 #endif
17 #ifndef MAX
18 #define	MAX(a,b) (((a)>(b))?(a):(b))
19 #endif
20 
21 // isfinite() on Solaris; from
22 // https://code.google.com/p/redis/issues/detail?id=20
23 #if defined(__sun) && defined(__GNUC__)
24 
25 #undef isnan
26 #define isnan(x) \
27       __extension__({ __typeof (x) __x_a = (x); \
28       __builtin_expect(__x_a != __x_a, 0); })
29 
30 #undef isfinite
31 #define isfinite(x) \
32       __extension__ ({ __typeof (x) __x_f = (x); \
33       __builtin_expect(!isnan(__x_f - __x_f), 1); })
34 
35 #undef isinf
36 #define isinf(x) \
37       __extension__ ({ __typeof (x) __x_i = (x); \
38       __builtin_expect(!isnan(__x_i) && !isfinite(__x_i), 0); })
39 
40 #undef isnormal
41 #define isnormal(x) \
42   __extension__ ({ __typeof(x) __x_n = (x); \
43                    if (__x_n < 0.0) __x_n = -__x_n; \
44                    __builtin_expect(isfinite(__x_n) \
45                                     && (sizeof(__x_n) == sizeof(float) \
46                                           ? __x_n >= __FLT_MIN__ \
47                                           : sizeof(__x_n) == sizeof(long double) \
48                                             ? __x_n >= __LDBL_MIN__ \
49                                             : __x_n >= __DBL_MIN__), 1); })
50 
51 #undef HUGE_VALF
52 #define HUGE_VALF (1e50f)
53 
54 #endif
55 
56 
57 // As suggested in http://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Function-Names.html
58 #if __STDC_VERSION__ < 199901L
59 # if __GNUC__ >= 2
60 #  define __func__ __FUNCTION__
61 # else
62 #  define __func__ "<unknown>"
63 # endif
64 #endif
65 
66 
67 /**
68    The qsort_r story:
69 
70    -qsort_r appears in BSD (including Mac OSX)
71          void qsort_r(void *, size_t, size_t,
72                       void *,
73                       int (*)(void *, const void *, const void *));
74 
75    -qsort_r appears in glibc 2.8, but with a different argument order:
76          void qsort_r(void*, size_t, size_t,
77                       int (*)(const void*, const void*, void*),
78                       void*);
79 
80    (Distributions including glibc 2.8 include:
81    -Mandriva 2009
82    -Ubuntu 8.10)
83 
84    Notice that the "thunk" and "comparison function" arguments to qsort_r are
85    swapped, and the "thunk" appears either at the beginning or end of the comparison
86    function.
87 
88    Previously, we did fancy footwork to detect and use a system version.
89 
90    Now, just ship a FreeBSD version!
91 
92    In Astrometry.net should instead use QSORT_R:
93 
94    void QSORT_R(void* base, size_t nmembers, size_t member_size,
95                 void* token, comparison_function);
96 
97    You should define the "comparison" function like this:
98 
99    static int QSORT_COMPARISON_FUNCTION(my_comparison, void* token, const void* v1, const void* v2) {
100      ...
101    }
102 
103    See ioutils.[ch]
104 */
105 
106 #endif
107