0812584985321c163db6802b8a036e610fa8c51a
[awesomized/libmemcached] / memcached / m4 / c99-backport.m4
1 # AC_PROG_CC_C99 ([ACTION-IF-AVAILABLE], [ACTION-IF-UNAVAILABLE])
2 # ----------------------------------------------------------------
3 # If the C compiler is not in ISO C99 mode by default, try to add an
4 # option to output variable CC to make it so. This macro tries
5 # various options that select ISO C99 on some system or another. It
6 # considers the compiler to be in ISO C99 mode if it handles _Bool,
7 # // comments, flexible array members, inline, long long int, mixed
8 # code and declarations, named initialization of structs, restrict,
9 # va_copy, varargs macros, variable declarations in for loops and
10 # variable length arrays.
11 AC_DEFUN([AC_PROG_CC_C99],
12 [AC_C_STD_TRY([c99],
13 [[#include <stdarg.h>
14 #include <stdbool.h>
15 #include <stdlib.h>
16 #include <wchar.h>
17 #include <stdio.h>
18
19 // Check varargs macros. These examples are taken from C99 6.10.3.5.
20 #define debug(...) fprintf (stderr, __VA_ARGS__)
21 #define showlist(...) puts (#__VA_ARGS__)
22 #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
23 static void
24 test_varargs_macros (void)
25 {
26 int x = 1234;
27 int y = 5678;
28 debug ("Flag");
29 debug ("X = %d\n", x);
30 showlist (The first, second, and third items.);
31 report (x>y, "x is %d but y is %d", x, y);
32 }
33
34 // Check long long types.
35 #define BIG64 18446744073709551615ull
36 #define BIG32 4294967295ul
37 #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
38 #if !BIG_OK
39 your preprocessor is broken;
40 #endif
41 #if BIG_OK
42 #else
43 your preprocessor is broken;
44 #endif
45 static long long int bignum = -9223372036854775807LL;
46 static unsigned long long int ubignum = BIG64;
47
48 struct incomplete_array
49 {
50 int datasize;
51 double data[];
52 };
53
54 struct named_init {
55 int number;
56 const wchar_t *name;
57 double average;
58 };
59
60 typedef const char *ccp;
61
62 static inline int
63 test_restrict (ccp restrict text)
64 {
65 // See if C++-style comments work.
66 // Iterate through items via the restricted pointer.
67 // Also check for declarations in for loops.
68 for (unsigned int i = 0; *(text+i) != '\0'; ++i)
69 continue;
70 return 0;
71 }
72
73 // Check varargs and va_copy.
74 static void
75 test_varargs (const char *format, ...)
76 {
77 va_list args;
78 va_start (args, format);
79 va_list args_copy;
80 va_copy (args_copy, args);
81
82 const char *str;
83 int number;
84 float fnumber;
85
86 while (*format)
87 {
88 switch (*format++)
89 {
90 case 's': // string
91 str = va_arg (args_copy, const char *);
92 break;
93 case 'd': // int
94 number = va_arg (args_copy, int);
95 break;
96 case 'f': // float
97 fnumber = va_arg (args_copy, double);
98 break;
99 default:
100 break;
101 }
102 }
103 va_end (args_copy);
104 va_end (args);
105 }
106 ]],
107 [[
108 // Check bool.
109 _Bool success = false;
110
111 // Check restrict.
112 if (test_restrict ("String literal") == 0)
113 success = true;
114 char *restrict newvar = "Another string";
115
116 // Check varargs.
117 test_varargs ("s, d' f .", "string", 65, 34.234);
118 test_varargs_macros ();
119
120 // Check flexible array members.
121 struct incomplete_array *ia =
122 malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
123 ia->datasize = 10;
124 for (int i = 0; i < ia->datasize; ++i)
125 ia->data[i] = i * 1.234;
126
127 // Check named initializers.
128 struct named_init ni = {
129 .number = 34,
130 .name = L"Test wide string",
131 .average = 543.34343,
132 };
133
134 ni.number = 58;
135
136 int dynamic_array[ni.number];
137 dynamic_array[ni.number - 1] = 543;
138
139 // work around unused variable warnings
140 return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x'
141 || dynamic_array[ni.number - 1] != 543);
142 ]],
143 dnl Try
144 dnl GCC -std=gnu99 (unused restrictive modes: -std=c99 -std=iso9899:1999)
145 dnl AIX -qlanglvl=extc99 (unused restrictive mode: -qlanglvl=stdc99)
146 dnl Intel ICC -c99
147 dnl IRIX -c99
148 dnl Solaris (unused because it causes the compiler to assume C99 semantics for
149 dnl library functions, and this is invalid before Solaris 10: -xc99)
150 dnl Tru64 -c99
151 dnl with extended modes being tried first.
152 [[-std=gnu99 -c99 -qlanglvl=extc99]], [$1], [$2])[]dnl
153 ])# AC_PROG_CC_C99
154
155 # AC_C_STD_TRY(STANDARD, TEST-PROLOGUE, TEST-BODY, OPTION-LIST,
156 # ACTION-IF-AVAILABLE, ACTION-IF-UNAVAILABLE)
157 # --------------------------------------------------------------
158 # Check whether the C compiler accepts features of STANDARD (e.g `c89', `c99')
159 # by trying to compile a program of TEST-PROLOGUE and TEST-BODY. If this fails,
160 # try again with each compiler option in the space-separated OPTION-LIST; if one
161 # helps, append it to CC. If eventually successful, run ACTION-IF-AVAILABLE,
162 # else ACTION-IF-UNAVAILABLE.
163 AC_DEFUN([AC_C_STD_TRY],
164 [AC_MSG_CHECKING([for $CC option to accept ISO ]m4_translit($1, [c], [C]))
165 AC_CACHE_VAL(ac_cv_prog_cc_$1,
166 [ac_cv_prog_cc_$1=no
167 ac_save_CC=$CC
168 AC_LANG_CONFTEST([AC_LANG_PROGRAM([$2], [$3])])
169 for ac_arg in '' $4
170 do
171 CC="$ac_save_CC $ac_arg"
172 _AC_COMPILE_IFELSE([], [ac_cv_prog_cc_$1=$ac_arg])
173 test "x$ac_cv_prog_cc_$1" != "xno" && break
174 done
175 rm -f conftest.$ac_ext
176 CC=$ac_save_CC
177 ])# AC_CACHE_VAL
178 case "x$ac_cv_prog_cc_$1" in
179 x)
180 AC_MSG_RESULT([none needed]) ;;
181 xno)
182 AC_MSG_RESULT([unsupported]) ;;
183 *)
184 CC="$CC $ac_cv_prog_cc_$1"
185 AC_MSG_RESULT([$ac_cv_prog_cc_$1]) ;;
186 esac
187 AS_IF([test "x$ac_cv_prog_cc_$1" != xno], [$5], [$6])
188 ])# AC_C_STD_TRY