portable way of detecting format of strerror_r
Costa Tsaousis (ktsaou) committed
Sep 27, 2016 at 11:56 UTC
a111eee06919e92b977aed6caf1bdb7dca172c56
3 files changed
+39
-14
configure.ac
+31
@@ -83,6 +83,37 @@ AC_TYPE_UINT16_T
83
AC_TYPE_UINT32_T
84
AC_C_INLINE
85
86
+# https://lists.gnu.org/archive/html/autoconf-commit/2012-12/msg00004.html
87
+# AC_C__GENERIC
88
+# -------------
89
+# Define HAVE_C__GENERIC if _Generic works, a la C11.
90
+AN_IDENTIFIER([_Generic], [AC_C__GENERIC])
91
+AC_DEFUN([AC_C__GENERIC],
92
+[AC_CACHE_CHECK([for _Generic], ac_cv_c__Generic,
93
+[AC_COMPILE_IFELSE(
94
+ [AC_LANG_SOURCE(
95
+ [[int
96
+ main (int argc, char **argv)
97
+ {
98
+ int a = _Generic (argc, int: argc = 1);
99
+ int *b = &_Generic (argc, default: argc);
100
+ char ***c = _Generic (argv, int: argc, default: argv ? &argv : 0);
101
+ _Generic (1 ? 0 : b, int: a, default: b) = &argc;
102
+ _Generic (a = 1, default: a) = 3;
103
+ return a + !b + !c;
104
+ }
105
+ ]])],
106
+ [ac_cv_c__Generic=yes],
107
+ [ac_cv_c__Generic=no])])
108
+if test $ac_cv_c__Generic = yes; then
109
+ AC_DEFINE([HAVE_C__GENERIC], 1,
110
+ [Define to 1 if C11-style _Generic works.])
111
+fi
112
+])# AC_C__GENERIC
113
+
114
+AC_C__GENERIC
115
+AC_FUNC_STRERROR_R
116
+
117
AC_ARG_VAR([MATH_CFLAGS], [C compiler flags for math])
118
AC_ARG_VAR([MATH_LIBS], [linker flags for math])
119
if test -z "${MATH_LIBS}"; then
src/common.h
-4
@@ -67,10 +67,6 @@
67
#ifdef __GNUC__
68
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
69
70
-#if GCC_VERSION < 40900
71
-#define WITHOUT_C11_GENERIC 1
72
-#endif
73
-
70
#if __x86_64__ || __ppc64__
71
#define ENVIRONMENT64
72
#else
src/log.c
+8
-10
@@ -266,17 +266,13 @@ void info_int( const char *file, const char *function, const unsigned long line,
266
// ----------------------------------------------------------------------------
267
// error log
268
269
-#ifdef WITHOUT_C11_GENERIC
270
-
271
-#ifdef STRERROR_R_POSIX
272
-// POSIX version of strerror_r
273
-static const char *strerror_result(int a, const char *b) { (void)a; return b; }
274
-#else
269
+#if defined(STRERROR_R_CHAR_P)
270
// GLIBC version of strerror_r
271
static const char *strerror_result(const char *a, const char *b) { (void)b; return a; }
277
-#endif
278
-
279
-#else /* ! WITHOUT_C11_GENERIC */
272
+#elif defined(HAVE_STRERROR_R)
273
+// POSIX version of strerror_r
274
+static const char *strerror_result(int a, const char *b) { (void)a; return b; }
275
+#elif defined(HAVE_C__GENERIC)
276
277
// what a trick!
278
// http://stackoverflow.com/questions/479207/function-overloading-in-c
@@ -288,7 +284,9 @@ static const char *strerror_result_string(const char *a, const char *b) { (void)
284
char *: strerror_result_string \
285
)(a, b)
286
291
-#endif /* ! WITHOUT_C11_GENERIC */
287
+#else
288
+#error "cannot detect the format of function strerror_r()"
289
+#endif
290
291
void error_int( const char *prefix, const char *file, const char *function, const unsigned long line, const char *fmt, ... )
292
{